Wednesday, September 7, 2011

Unit Tests I

This series discusses some approaches to unit testing HelloWorld. In this post, we learn the difference between Logic Tests and Application Tests, then illustrates how to set up some skeleton unit test files in your Xcode project.

(Note: If you do not already have a 'Tests' group or target within your project, additional configuration will be required that is beyond the scope of this post. As a workaround, create a new project, and make sure 'Include Unit Tests' is checked during the setup process.)

Logic Tests vs. Application Tests
So far, the HelloWorld application runs fine. However, it is usually a best practice to write unit tests for an application to ensure its behavior does not change unintentionally over time. The Apple developer library briefly describes how to set up unit tests in your Xcode project in the following document:
This document differentiates between two different kinds of tests. In Apple parlance, they are:
  • Logic Tests - test logic of individual classes (also known as Unit testing).
  • Application Tests - test integration of application as a whole (also known as Integration testing).
With Logic Tests, one instantiates application classes manually and calls specific methods on them, then confirms that the return values match expectations. With Application Tests, one obtains a reference to the application's UIApplicationDelegate and programmatically interacts with the app to enter text in fields, simulate button clicks, and such.

Fortunately, Xcode 4 is equipped to generate empty unit test files for both of these. The tests will be run from within the iOS Simulator using the SenTestingKit framework. To create an empty stub test, open Xcode and select File > New > New File, or simply press ⌘N. Then select "Objective-C test case class" and press Next.




In this dialog, one has the opportunity to name the new test class, and also choose whether it is a Logic test or an Applicaton test. The difference between the two is trivial. By default the stub Logic test class includes a test method like this:

- (void)testMath
{
STAssertTrue((1 + 1) == 2, @"Compiler isn't feeling well today :-(");
}
and by default the stub Application test class will include a test method like this:

- (void)testAppDelegate
{
id yourApplicationDelegate = [[UIApplication sharedApplication] delegate];
STAssertNotNil(yourApplicationDelegate, @"UIApplication failed to find the AppDelegate");
}
Choose a test type and name the class, then click Next.




This last dialog asks for a destination group and build target for the new files. Choose an existing 'Tests' group and its corresponding target. (If the application target is also checked, uncheck that or you will get build errors.) Click Create to finish.


As written above, both Logic Tests and Application Tests should pass. Build and run the tests by selecting Project > Test, or simply press ⌘U.