-
Notifications
You must be signed in to change notification settings - Fork 252
add device agnostic tests & add helpful assertion for device agnostic tests #137
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at [email protected]. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
- re-record all snapshots - point to FBSnapshotTestCase fork w/ a fix for screen size suffix (PR is already up: facebookarchive/ios-snapshot-test-case#137) - add "WMFVisualTestBatchRecordMode" to make it easier to re-record all snapshot tests
looks like I need to download iOS 9.0 sim and re-record snapshots. downloading now... ⏳ |
@@ -34,7 +34,7 @@ BOOL FBSnapshotTestCaseIs64Bit(void) | |||
NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName) | |||
{ | |||
UIDevice *device = [UIDevice currentDevice]; | |||
CGSize screenSize = [[UIApplication sharedApplication] keyWindow].bounds.size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this change is OK.
UIWindow != UIScreen -> UIWindow is unique for application (especially useful for split view), and UIScreen is for whole device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, but I figured using the screen would:
- Be equivalent to the window in most cases
- Work when the library is integrated as a framework (where
keyWindow
does not)
Maybe a more comprehensive way to solve this would be to generate the suffix based on the view being tested, which is probably what you really want anyway. This makes even more sense when you consider that snapshots are generated based on the bounds of the specified view, even creating and "keying" a window if necessary.[0]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, we could check if the keyWindow
is nil
and if it is, create a window with the [[UIScreen mainScreen] bounds]
How does this sound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, just had a realization: the problem doesn't have anything to do with frameworks. Our app short-circuits itself when being run as the test host, which means no AppDelegate
, which means no keyWindow
.
So, this is more about handling our specific edge case, which means that a window should be made the keyWindow
before suffixes are generated. At which point, I'm wondering if we should be using a "dummy" app delegate (which just has a dummy window), or FBSnapshotTestCase should install one for me (e.g. if you were running a Logic Tests target which didn't even have a host).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had similar problem:
I write some framework which is using UIApplication. Same framework doesn't have UIApplication, so I created TestApp, which hosts tests.
So check if this resolve your problem:
- Add new Application target
- Choose your framework test target
- Go to
general
tab - Set your new Application target as
Host Application
- Make sure that your Application target contains framework tests in test schema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, if that works maybe we can assert and explain how to solve this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Grubas7 the short-circuit is intentional, and our app is already the "Host" for our tests. This removes the unnecessary "link in both targets" step when adding new app code.
My question to you guys is, should FBSnapshotTestCase be defensive by setting the keyWindow
itself (which it already tries to do), and if so, should it guarantee that keyWindow
is available at file suffix generation time? For example, we could use a category on UIApplication
that gets or creates a key window.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My question above determines whether the solution should be either:
- Add an assertion and explain what users should do (set a host app or otherwise create a key window when visual tests are running)
- Create a
keyWindow
manually if necessary
{ | ||
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; | ||
redView.backgroundColor = [UIColor redColor]; | ||
FBSnapshotVerifyView(redView, nil); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Travis is hitting the assertion that you added, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, will have to investigate..
On Sun, Dec 13, 2015 at 17:30 Patrick Chamelo [email protected]
wrote:
In
FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDeviceAgnosticTests.m
#137 (comment)
:+@EnD
+
+@implementation FBSnapshotTestCaseDeviceAgnosticTests
+
+- (void)setUp
+{
- [super setUp];
- self.deviceAgnostic = YES;
- self.recordMode = NO;
+}
+- (void)testViewSnapshot
+{
- UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
- redView.backgroundColor = [UIColor redColor];
- FBSnapshotVerifyView(redView, nil);
Travis is hitting the assertion that you added, why?
—
Reply to this email directly or view it on GitHub
https://github.com/facebook/ios-snapshot-test-case/pull/137/files#r47451523
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the keyWindow
is nil
... 😖 Even though the app delegate is certainly making it key and visible. Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also @Grubas7 this is why the tests were added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I:
- Somehow wait for the application to have a key window, maybe using
expectationWithPredicate
? - Fall back to the application's delegate's window?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you suggest? poll keyWIndow
in FBSnapshotTestCase.setUp
? e.g.:
- (void)setUp
{
// other stuff
[self expectationWithPredicate:[NSPredicate predicateWithBlock:^ (...) {
return evaluatedObject.keyWindow != nil;
} ...];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I had to look at it a bit to figure out what is going on and there are a couple of issues:
- The build script that I added on travis is building and testing both iPhone 5 and iPhone 6, so we have to record the image for both of these devices.
- The build script runs the FBSnapshotControllerTests and in particular testFailedImageWithDeviceAgnosticShouldHaveModelOnName. These tests don't have an application associated with, so we hit the assertion. Maybe we can make the window a parameter and simply write tests to make sure that FBDeviceAgnosticNormalizedFileName is working as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bgerstle thoughts on my latest comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I didn't see the updated commits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nscoding yeah, sorry I didn't respond, but better late than never:
The build script that I added on travis is building and testing both iPhone 5 and iPhone 6, so we have to record the image for both of these devices.
I already figured that out when Travis failed and downloaded/recorded the proper screenshots.
testFailedImageWithDeviceAgnosticShouldHaveModelOnName. These tests don't have an application associated with, so we hit the assertion.
Those tests are in the Demo project, which does have a host application (see above screenshot). I think the problem was that UIImage+Snapshot
was causing issues when installing a "dummy" window when given a view without a window. This somehow caused the keyWindow
to return nil
when device-agnostic tests were run—which I determined after seeing each test pass in isolation. As a result, I've modified UIImage+Snapshot
to use the application's keyWindow
if the given view doesn't have a window (or if it isn't a window itself). Let me know if you think this is acceptable.
Maybe we can make the window a parameter and simply write tests to make sure that FBDeviceAgnosticNormalizedFileName is working as expected.
That could be useful for verifying the formatting of test names (to prevent unintended regressions and thus break tests for users), but doesn't address the problems targeted by this PR.
- re-record all snapshots - point to FBSnapshotTestCase fork w/ a fix for screen size suffix (PR is already up: facebookarchive/ios-snapshot-test-case#137) - add "WMFVisualTestBatchRecordMode" to make it easier to re-record all snapshot tests
@Grubas7 @nscoding this should be ready to go, see my latest comment for a brief explanation on the approach and c9a9530 for the implementation |
|
||
@implementation UIApplication (StrictKeyWindow) | ||
|
||
- (UIWindow*)fb_strictKeyWindow { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space before asterisk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you guys considered using uncrustify or clang-format? 😅 While I'm at it, should I remove the comment headers (Created by Brian Gerstle etc.)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
went ahead and did it anyway
Looks good 👍 |
@Grubas7 thanks for the feedback! all your comments should be addressed 👌 |
@bgerstle could you squash your commits? |
027784b
to
c2b8911
Compare
@Grubas7 squashed & amended commit message |
|
||
@implementation UIApplication (StrictKeyWindow) | ||
|
||
- (UIWindow *)fb_strictKeyWindow { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new line before {
Thank you for working on this, it looks great, I left a couple of comments (nit picks really). |
@nscoding addressed all of your comments, including the iPhone 6 screen size issue (and re-recorded reference image), squashed, and re-pushed |
testSuccessfulComparisonOfDeviceAgnosticReferenceImages tests are failing, it's looking for 320x568 (iPhone 5 right? but we didn't provide this one) |
Ahh that's different now too, as it used to be 320x480, forgot to re-record
|
Use UIApplication.keyWindow instead of a manually-created & installed window when snapshotting a view w/o a window. This prevents keyWindow from being `nil` when generating device-agnostic reference image filenames. Accessing keyWindow is done through a category, so as to always throw an assertion if it is nil, instructing developers to make sure their tests have a host application w/ a key window.
@nscoding should be good now 🏁 |
@@ -0,0 +1,50 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the launch screen fixes the issue where the app doesn't fill the
screen.
On Fri, Jan 8, 2016 at 12:50 Patrick Chamelo [email protected]
wrote:
In FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemo/Launch Screen.storyboard
#137 (comment)
:@@ -0,0 +1,50 @@
+
+Do we need this?
—
Reply to this email directly or view it on GitHub
https://github.com/facebook/ios-snapshot-test-case/pull/137/files#r49236579
.
add device agnostic tests & add helpful assertion for device agnostic tests
This happens when snapshotting the key window. This was introduced by facebookarchive#137.
Our app doesn't have a window when run as a test host, which results in
keyWindow
beingnil
. This could also happen if your test target is a "Logic Test", and not an "Application Test."I've added an assertion so others can get clearer feedback about what's going wrong and how to fix it. FBSnapshotTestCase could arguably create a
keyWindow
implicitly, but I figured it's better to let users set up their test host properly instead of implicitly relying on the library to do it for them.