1

I wonder how a UIViewcontroller came to know that which test file it needs to pick.

E.g. I have a big project with lots of UIViewcontrollers in it.

And I want to make separate test files for each controller. Like 1 for login, another for profile UIViewcontroller.

I know framework is in early stage but any help is appreciated.

Thanks.

Aaron Golden
  • 7,092
  • 1
  • 25
  • 31

1 Answers1

4

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"
                                                     }];
Jeffrey Wear
  • 1,155
  • 2
  • 12
  • 24