Inherits from NSObject
Declared in SLTest.h

Overview

SLTest is the abstract superclass of Subliminal integration tests.

To write a test, developers create a new subclass of SLTest. They then add test case methods and implement set-up and tear-down methods as necessary.

The methods in the SLTest (SLTestCase) category are used to set up before and clean up after individual test case methods. Test case methods are methods, defined on a subclass of SLTest:

  • whose names have the prefix “test”,
  • with void return types, and
  • which take no arguments.

When a test is run, it discovers, sets up, runs, and tears down all its test cases. The method descriptions below specify when each method will be called, and [SLTestTests testCompleteTestRunSequence] gives an example.

A test case “passes” if it throws no exceptions in its set-up, tear-down, or the body of the test case itself; otherwise, it “fails”. That failure is “expected” if it was caused by a test assertion failing. Any other exception causes an “unexpected” failure.

Tasks

Retrieving Tests to Run

  • + allTests

    Returns all tests linked against the current target.

  • + testNamed:

    Returns the SLTest subclass with the specified name.

Conditionalizing Test Runs

  • + isAbstract

    Returns YES if this class does not define test cases.

  • + supportsCurrentPlatform

    Returns YES if this test has at least one test case which can be run given the current device, screen, etc.

  • + isFocused

    Returns YES if the test has at least one test case which is focused and which can run on the current platform.

Ordering Test Runs

  • + runGroup

    Returns a value identifying the group of tests to which the receiver belongs.

Running a Test

Running Test Cases

Class Methods

allTests

Returns all tests linked against the current target.

+ (NSSet *)allTests

Return Value

All tests (SLTest subclasses) linked against the current target.

Discussion

The recommended way to run Subliminal tests is to invoke [SLTestController runTests:withCompletionBlock:] with the set returned by this method. That way, new tests will automatically be discovered and run.

Without modifying the argument to [SLTestController runTests:withCompletionBlock:], tests may be conditionalized to run only in certain circumstances using APIs like isAbstract, supportsCurrentPlatform, and isFocused.

Declared In

SLTest.h

isAbstract

Returns YES if this class does not define test cases.

+ (BOOL)isAbstract

Return Value

YES if the class is without test cases, otherwise NO.

Discussion

An abstract test will not itself be run. Subclasses which do define test cases will be run, however, allowing a single base class to define set-up and tear-down work shared among related subclasses. Abstract classes can also be used to define the run group shared by subclasses.

Declared In

SLTest.h

isFocused

Returns YES if the test has at least one test case which is focused and which can run on the current platform.

+ (BOOL)isFocused

Return Value

YES if any test cases are focused and can be run on the current platform, NO otherwise.

Discussion

When a test is run, if any of its test cases are focused, only those test cases will run. This may be useful when writing or debugging tests.

A test case is focused by prefixing its name with “focus_”, like so:

- (void)focus_testFoo;

It is also possible to implicitly focus all test cases by prefixing their test’s name with “Focus_”. But if some test cases are explicitly focused (as above), only those test cases will run—the narrowest focus applies.

If a test is focused, that focus will apply to any tests which descend from it.

Warning: Methods that take test case selectors as arguments (like setUpTestCaseWithSelector:) are invoked with the unfocused form of the selectors —they need not (and should not) be modified when a test case is focused.

Warning: Focused test cases will not be run if their test is not run (e.g. if it is not included in the set of tests to be run, or if it does not support the current platform).

Declared In

SLTest.h

runGroup

Returns a value identifying the group of tests to which the receiver belongs.

+ (NSUInteger)runGroup

Return Value

A value identifying the group of tests to which the receiver belongs. The default implementation returns 1: all tests will be part of a single run group.

Discussion

SLTestController will run tests in ascending order of group, and then within each group, in a randomized order. This allows test writers to provide a rough order to tests, where necessary, while minimizing the test pollution that can result from an absolute ordering.

A common use for run groups is to divide tests into two groups, those that need to occur before some “startup” event (an onboarding flow, an import process, etc.) (of run group 1) and those that need to occur afterward (of run group 2). In this scenario, the “post-startup” tests subclass an abstract test that, in its implementation of setUpTest, causes the startup event to happen. Altogether, this ensures that all of the “pre-startup” tests run before any of the “post-startup” tests run—and that startup happens before any of the “post-startup” tests happen—while allowing the tests within each group to run in any order.

Declared In

SLTest.h

supportsCurrentPlatform

Returns YES if this test has at least one test case which can be run given the current device, screen, etc.

+ (BOOL)supportsCurrentPlatform

Return Value

YES if this class has test cases that can currently run, NO otherwise.

Discussion

Subclasses of SLTest should override this method if some run-time condition should determine whether or not all test cases should run. Typical checks might include checking the user interface idiom (phone or pad) of the current device, or checking the scale of the main screen.

As a convenience, test writers may specify the device type(s) on which a test can run by suffixing tests' names in the following fashion:

  • A test whose name has the suffix “_iPhone,” like “TestFoo_iPhone”, will be executed only when ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) is true.
  • A test whose name has the suffix “_iPad” will be executed only when the current device user interface idiom is UIUserInterfaceIdiomPad.
  • A test whose name has neither the “_iPhone” nor the “_iPad” suffix will be executed on all devices regardless of the user interface idiom.

The default implementation of this method checks that the class is suffixed appropriately and that there is at least one test case for which testCaseWithSelectorSupportsCurrentPlatform: returns YES.

If this method returns NO, none of this test’s cases will run.

Declared In

SLTest.h

testCaseWithSelectorSupportsCurrentPlatform:

Returns YES if this test case can be run given the current device, screen, etc.

+ (BOOL)testCaseWithSelectorSupportsCurrentPlatform:(SEL)testCaseSelector

Parameters

testCaseSelector

A selector identifying a test case.

Return Value

YES if the test case can be run, NO otherwise.

Discussion

Subclasses of SLTest should override this method if they need to do any run-time checks to determine whether or not specific test cases can run. Typical checks might include checking the user interface idiom (phone or pad) of the current device, or checking the scale of the main screen.

As a convenience, test writers may specify the device type(s) on which a test case can run by suffixing test cases' names in the following fashion:

  • A test case whose name has the suffix “_iPhone,” like “testFoo_iPhone”, will be executed only when ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) is true.
  • A test case whose name has the suffix “_iPad” will be executed only when the current device user interface idiom is UIUserInterfaceIdiomPad.
  • A test case whose name has neither the “_iPhone” nor the “_iPad” suffix will be executed on all devices regardless of the user interface idiom.

The default implementation of this method checks that the selector is suffixed appropriately.

Warning: If the test does not support the current platform, that test’s cases will not be run regardless of this method’s return value.

Declared In

SLTest.h

testNamed:

Returns the SLTest subclass with the specified name.

+ (Class)testNamed:(NSString *)name

Parameters

name

The name of the test (SLTest subclass) to return.

Return Value

The SLTest subclass with the specified name, or nil if no SLTest subclass with that name is linked against the current target.

Discussion

This method may be used to retrieve a single SLTest, e.g. to pass to [SLTestController runTests:withCompletionBlock:], without having to import that test’s interface.

Note that it may be easier to run a single test by focusing that test than by modifying the arguments to [SLTestController runTests:withCompletionBlock:].

Declared In

SLTest.h

Instance Methods

recordLastKnownFile:line:

Records a filename and line number to attach to an exception thrown at that source line.

- (void)recordLastKnownFile:(const char *)filename line:(int)lineNumber

Parameters

filename

A filename, i.e. the last component of the __FILE__ macro’s expansion.

lineNumber

A line number, i.e. the __LINE__ macro’s expansion.

Discussion

Used by the UIAElement and test assertion macros so that exceptions thrown by SLUIAElement methods and/or test assertions may be traced to their origins.

Declared In

SLTest.h

runAndReportNumExecuted:failed:failedUnexpectedly:

Runs all test cases defined on the receiver’s class, and reports statistics about their execution.

- (BOOL)runAndReportNumExecuted:(NSUInteger *)numCasesExecuted failed:(NSUInteger *)numCasesFailed failedUnexpectedly:(NSUInteger *)numCasesFailedUnexpectedly

Parameters

numCasesExecuted

If this is non-NULL, on return, this will be set to the number of test cases that were executed—which will be the number of test cases defined by the receiver’s class.

numCasesFailed

If this is non-NULL, on return, this will be set to the number of test cases that failed (the number of test cases that threw exceptions).

numCasesFailedUnexpectedly

If this is non-NULL, on return, this will be set to the number of test cases that failed unexpectedly (those test cases that threw exceptions for other reasons than test assertion failures).

Return Value

YES if the test successfully finished (all test cases were executed, regardless of their individual success or failure), NO otherwise (an exception occurred in test case set-up or tear-down ).

Discussion

See SLTest (SLTestCase) for a discussion of test case execution.

Warning: If an exception occurs in test case set-up, the test’s cases will be skipped. Thus, the caller should use the values returned in numCasesExecuted, numCasesFailed, and numCasesFailedUnexpectedly if and only if this method returns YES.

Declared In

SLTest.h

setUpTest

Called before any test cases are run.

- (void)setUpTest

Discussion

In this method, tests should establish any state shared by all test cases, including navigating to the part of the app being exercised by the test cases.

In this method, tests can (and should) use test assertions to ensure that set-up was successful.

Warning: If set-up fails, this test will be aborted and its cases skipped. However, tearDownTest will still be executed.

Warning: Unlike the -setUp method found in OCUnit and other JUnit-inspired frameworks, -setUpTest is called only once per test.

See Also

Declared In

SLTest.h

setUpTestCaseWithSelector:

Called before each test case is run.

- (void)setUpTestCaseWithSelector:(SEL)testCaseSelector

Parameters

testCaseSelector

The selector identifying the test case about to be run.

Discussion

In this method, tests should establish any state particular to the specified test case.

In this method, tests can (and should) use test assertions to ensure that set-up was successful.

Warning: If set-up fails, the test case will be logged as having failed, and the test case itself will be skipped. However, tearDownTestCaseWithSelector: will still be executed.

Declared In

SLTest.h

tearDownTest

Called after all test cases are run.

- (void)tearDownTest

Discussion

In this method, tests should clean up any state shared by all test cases, such as that which was established in setUpTest.

In this method, tests can (and should) use test assertions to ensure that tear-down was successful.

Warning: If tear-down fails, the test will be logged as having terminated abnormally rather than finished, but its test cases' logs will be preserved.

Warning: Unlike the -setUp method found in OCUnit and other JUnit-inspired frameworks, setUpTest is called only once per test.

See Also

Declared In

SLTest.h

tearDownTestCaseWithSelector:

Called after each test case is run.

- (void)tearDownTestCaseWithSelector:(SEL)testCaseSelector

Parameters

testCaseSelector

The selector identifying the test case that was run.

Discussion

In this method, tests should clean up state particular to the specified test case, such as that which was established in setUpTestCaseWithSelector:.

In this method, tests can (and should) use test assertions to ensure that tear-down was successful.

Warning: If tear-down fails, this test case will be logged as having failed even if the test case itself succeeded. However, the test case’s logs will be preserved.

Declared In

SLTest.h

wait:

Suspends test execution for the specified time interval.

- (void)wait:(NSTimeInterval)interval

Parameters

interval

The time interval for which to wait.

Discussion

Only use this method to wait (for the UI to update, or for the application to complete some operation) if a delay is found to be necessary, and it is not possible to describe a specific condition on which to wait.

It should not be necessary to wait before attempting to access interface elements when the delay would be less than the default timeout: elements automatically wait to become valid and/or tappable if access requires waiting.

Where the delay would be more than the default timeout, or where the condition on which to wait involves application state not made apparent by the UI, using the SLAssertTrueWithTimeout macro will result in a clearer, more efficient test than using -wait:. See the definition of SLAssertTrueWithTimeout for examples.

Declared In

SLTest.h