Xcode’s 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 it to detect potential regressions in your code or validate the behavior of your application. These capabilities can add tremendous value to your projects. In particular, they can improve the stability of your code greatly by ensuring individual pieces of code behave in expected ways.
Of course, the amount of stability you receive from unit testing is highly dependent on the quality of the test cases you write. The following are some guidelines to think about when writing test cases:
One test is infinitely better than no tests at all. One test ensures that your code compiles, links and can run.
Whenever a bug is fixed, write one or more test cases to verify that the behavior remains fixed.
Use dependent targets to make it easier to run tests regularly. Running tests regularly can help identify problems before they are committed to your source code repository.
Check boundary conditions heavily. If the parameter of a method expects values in a specific range, your tests should pass in values that lie across that range. For example, if an integer parameter can have values between 0 and 100 inclusive, three variants of your test might pass in the values 0, 50, and 100 respectively.
Use negative tests to be sure your code responds to error conditions appropriately. Verify that your code behaves appropriately when it receives invalid or unexpected input values. Verify that it returns errors or throws exceptions when it should. You might be surprised to find that a test you expected to fail actually succeeds. For example, if an integer parameter to a method can accept values in the range 0 to 100 inclusive, you might create tests that pass in the values -1 and 101.
Write tests that combine different code modules to implement some of the more complex behaviors of your application. While simple, isolated tests do provide value, stacked tests that exercise complex behaviors tend to catch many more problems. These kinds of tests simulate the behavior of your code under more realistic conditions, which leads to the discovery of more realistic problems. For example, in addition to just adding objects to an array, you could create the array, add several objects to it, remove a few of those objects using several different methods, and then make sure the number of remaining objects is correct.
Don’t stress about unit tests. They are intended as a tool for ensuring good test coverage and memory management. Use them in that way to aid your development process.
Last updated: 2009-10-19