Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for TestFlight methods in spaceship and fastlane_core #8962

Merged
merged 41 commits into from Apr 28, 2017

Conversation

snatchev
Copy link
Member

Future of spaceship testing:

  • No fixtures: these are too brittle to maintain
  • Use sinatra app to construct client responses near the test site
  • More focus on each Unit isolation. Heavier use of mock objects

This is a work in progress

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.

Motivation and Context

Description

@fastlane-bot-helper
Copy link
Contributor

fastlane-bot-helper commented Apr 21, 2017

1 Warning
⚠️ Big PR

Generated by 🚫 Danger

@hjanuschka
Copy link
Collaborator

wow! ❤️ i am in love with the sinatra + json sheme approach! 👍

@@ -104,7 +104,7 @@ def self.latest(app_id: nil, platform: nil)
#
# Note: this will overwrite any non-saved changes to the object
#
# @return (Spaceceship::Base::DataHash) the raw_data of the build.
# @return (Spaceship::Base::DataHash) the raw_data of the build.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find!


def get_groups(app_id: nil)
def put_testinfo(app_id: nil, testinfo: nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we call this anywhere that it needs to get updated?

Also, just curious why this is changed to know about the model object rather than passing in the fields?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good question. We currently don't use it. I did use it at one point in a debugging phase to try to fix the problem with our shared test account.

I think it's okay to pass in objects that look like hashes (or at least respond to to_json) as long as they don't need any mutation to result in a successful response. Here, the client doesn't really know anything about testinfo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just read the comment above about passing in large objects. Got it!

#
# @return (Spaceship::TestFlight::Build)
def self.find(app_id: nil, build_id: nil)
attrs = client.get_build(app_id: app_id, build_id: build_id)
self.new(attrs) if attrs
self.new(attrs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be safe to have this return a Build object without any attributes? Might cause an issue if we are checking for its presence at any point right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize always expects a hash. If nil is passed in, it throws an exception. So far the pattern has been that if an error response is received, an UnexpectedResponse exception is thrown. I think throwing exceptions is consistent in this case.


def get_groups(app_id: nil)
def put_testinfo(app_id: nil, testinfo: nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just read the comment above about passing in large objects. Got it!

require 'spec_helper'

describe Spaceship::TestFlight::Tester do
let(:tester) { Spaceship::TestFlight::Tester.new }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mpirri Is this being used?

@mpirri mpirri changed the title [WIP] Add testing framework for spaceship Add tests for TestFlight methods in spaceship and fastlane_core Apr 27, 2017
it 'waits when a build is still processing' do
expect(Spaceship::TestFlight::Build).to receive(:all_processing_builds).and_return([processing_build])
expect(Spaceship::TestFlight::Build).to receive(:builds_for_train).and_return([processing_build], [ready_build])
expect(FastlaneCore::BuildWatcher).to receive(:sleep).with(10)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: change this to expect(FastlaneCore::BuildWatcher).to receive(:sleep)

That way, if we ever change how long we want it to sleep, we don't have to go back and update all the tests where we expected a particular number

# Essentially, we are making a class-inheritable-accessor as described here:
# https://apidock.com/rails/v4.2.7/Class/class_attribute
#
# TODO[snatchev]: move this into spaceship/base.rb once all the tests pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODONE?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, that was a cryptic comment - are we now in a place where this TODO could be resolved?

Copy link
Contributor

@mfurtak mfurtak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome - I'd definitely like a run-down on how it all works, though 😉

Might it make sense to update some spaceship developer docs to explain the strategy?

@mpirri mpirri force-pushed the snatchev/testing-framework-2 branch from 3d8f4c5 to 8691c9b Compare April 27, 2017 19:50

platform ||= "ios"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform will never be nil because of the assertion above. Perhaps we should set platform: 'ios' in the parameter names, or get rid of this.

@snatchev
Copy link
Member Author

I agree with @mfurtak about adding some documentation. Where should we add some developer docs?

  • at the top of some classes
  • a README in the relevant folder (i.e. spaceship/spec)?
  • in another designated documentation location?

@ohayon
Copy link
Contributor

ohayon commented Apr 27, 2017

I think a README.md in the spaceship/spec directory would make sense. @mfurtak thoughts on where the best place for this would be is?

**Examples:**

Mocked responses:
At the top of your data model, set the client to be a `mock_client`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"At the top of your data model spec"?


Spaceship wraps various APIs using the following pattern:

A simple `client` and various data models, usually suclassed from a `Base` model (e.g. Spaceship::TestFlight::Base)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"suclassed" -> "subclassed"


```ruby
before do
mock_client_response(:get_tester, with: { tester_id: 1 }) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this method come from? Is there something that has to be required in the spec to make it work?

end
```

The first parameter is the name of the method we are mocking, and `with:` parameter specifies some required parameter to that method. If you don't give it a `with:`, the mock will accept any parameter. The block is the return value of calling `client.get_tester`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be more than one parameter? If so, is it more clear to say "required parameters" and "any parameters"?

Copy link
Contributor

@mfurtak mfurtak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great, thanks for the docs 👍 Just left a few questions - merge when ready

@ohayon ohayon merged commit 1ad43dd into master Apr 28, 2017
@ohayon ohayon deleted the snatchev/testing-framework-2 branch April 28, 2017 15:00
@mpirri mpirri mentioned this pull request Apr 28, 2017
@@ -130,6 +130,10 @@ def export_compliance_missing?
external_state == BUILD_STATES[:export_compliance_missing]
end

def self.processed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be def processed?, not def self.processed?

NoMethodError: [!] undefined method `processed?' for #<Spaceship::TestFlight::Build:0x007fb066700ee0>
gems/fastlane-2.28.6/fastlane_core/lib/fastlane_core/build_watcher.rb:15:in `block in wait_for_build_processing_to_be_complete'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for bringing this to our attention! I can't believe with all the unit tests we added that we missed this...

Anyhow, here is a PR to fix it: #9025
As soon as we can get a 🚢 on it, we will release a new build.

@fastlane-bot
Copy link

Congratulations! 🎉 This was released as part of fastlane 2.28.6 🚀

@fastlane fastlane locked and limited conversation to collaborators Jul 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants