In Subliminal, the tests drive your application, not the other way around. You can definitely have tests that correspond to different view controllers, but the tests are responsible for navigating to those controllers' views within the application.
That navigation is generally done within tests' implementations of -setUpTest
. Let's say that your application opens to a "home" screen, on which there is a button titled "Log in"; and that pressing that button causes a "login view controller" to be presented. The way you'd test that view controller would be to add a test like this to your integration tests target:
@interface LoginTest : SLTest
@end
@implementation
- (void)setUpTest {
// make sure we're at "Home", then:
SLButton *loginButton = [SLButton elementWithAccessibilityLabel:@"Log in"];
[loginButton tap];
}
/*
now test the login view controller:
- (void)testThat... { }
*/
- (void)tearDownTest {
// log out and go back to "Home"
}
@end
Note that it's very important that your tests begin and end at known locations, in -setUpTest
and -tearDownTest
, respectively--you can't depend on Subliminal tests executing in a particular order.
So how would you test the profile screen, then? Let's say that, in your application, the profile was shown immediately after logging in. Then, a profile test would look something like this:
@interface ProfileTest : SLTest
@end
@implementation
- (void)setUpTest {
// Log in
}
/*
now test the profile view controller:
- (void)testThat... { }
*/
- (void)tearDownTest {
// log out and go back to "Home"
}
@end
You see that ProfileTest
should do what it needs to get to the view it wants to test--in this case, logging in. (This is why it's important that LoginTest
logs out and goes back to "home" in -tearDownTest
, so that ProfileTest
will start from a known state even if LoginTest
executes first).
To make this setup process easier, you can use "app hooks". With LoginTest
verifying that the login UI works, it's not important that ProfileTest
goes through that UI. Instead, it can ask the application to log in. Right before your application delegate launched the tests, it might register a "login manager" singleton as being able to programmatically log a test user in:
[[SLTestController sharedTestController] registerTarget:[LoginManager sharedManager]
forAction:@selector(logInWithInfo:)];
Then, -[ProfileTest setUpTest]
could call:
[[SLTestController sharedTestController] sendAction:@selector(logInWithInfo:)
withObject:@{
@"username": @"john@foo.com",
@"password": @"Hello1234"
}];