Retired Document
Important: This version of Unit Testing Guide has been retired. The replacement document focuses on the new testing features and workflow provided by Xcode 5 and later revisions. For information covering the same subject area as this page, please see Testing with Xcode.
Writing Testable Code
The Xcode integrated support for unit-testing makes it possible for you to build test suites to support your development efforts in any way you want. You can use unit-testing in Xcode to detect potential regressions in your code or to validate the behavior of your app. This testing can improve the stability of your code by ensuring that units behave in the expected ways.
Of course, the level of stability you achieve through unit-testing is highly dependent on the quality of the test cases you write. Follow these guidelines as you write code, to ensure that it’s easily testable:
Define API requirements. You should define requirements and outcomes for each method or function that you add to your project. These requirements should include input and output ranges, exceptions thrown and the conditions under which they are raised, and the type of values returned (especially if the values are instances of classes). Specifying requirements and making sure that requirements are met in your code help you write robust, secure code.
See the Unit Testing Apps and Frameworks sample-code project for an example of using exceptions to identify and report incorrect library usage by client code.
Write test cases as you write code. As you design and write each method or function, write one or more test cases that ensure that the API’s requirements are met. It’s harder to write unit tests for existing code than for code you are writing.
Check boundary conditions. If a parameter of a method must have values in a specific range, your tests should pass values that include the lowest and highest values of the range. For example, if a procedure has an integer parameter can have values between 0 and 100, inclusive, the test code for that method should pass the values 0, 50, and 100 for the parameter.
Use negative tests. Negative tests ensure that your code responds to error conditions appropriately. Verify that your code behaves correctly when it receives invalid or unexpected input values. Also verify that it returns error codes or raises exceptions when it should. For example, if an integer parameter must have values in the range 0 to 100, inclusive, you should create test cases that pass the values -1 and 101 to ensure that the procedure raises an exception or returns an error code.
Write comprehensive test cases. Comprehensive tests combine different code modules to implement some of the more complex behavior of your API. While simple, isolated tests provide value, stacked tests exercise complex behaviors and tend to catch many more problems. These kinds of tests mimic the behavior of your code under more realistic conditions. For example, in addition to adding objects to an array, you could create the array, add several objects to it, remove a few of them using different methods, and then ensure that the set and number of remaining objects is correct.
Cover your bug fixes with test cases. Whenever you fix a bug, write one or more tests cases that verify the fix.
Copyright © 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-09-18