Wolf (a.k.a. “Jon”) pointed out to me that I don’t want to compile my tests into my application all the time, which my last post assumed I could do. Why? Because with the amount of tests you’re supposed to write, this could easily double the size of your application. But I don’t want target A that builds my code, and target B that builds my code+tests. I only want to build the code once!
The solution is to put as many of the tests as you can in a separate embedded framework. When you run or start a debugging session with the app, the framework is loaded at startup. OCUnit automatically runs the tests. Adding the tests is a copy phase, not a rebuild. Stripping the tests is as simple as not copying the framework into the application bundle. (This only works if you weak-link the framework; if you link the test framework regularly, then you’ll get linker errors when you run the app without it.)
I tried this with my much-abused TestExtras example from OCUnit, and immediately ran into a problem. The test framework needs to refer to the objects it’s testing, but you can’t link a framework against an application. (At least, not that I know of.) To get around this, my TestExtras application has two frameworks. One for the classes used by the application. Another for the tests on those classes.
I added the Person class from the first example in the OCUnit tutorial to my app framework, called Person.framework. I then added Person’s test class, PersonTest, to my Test.framework.
I linked against SentTestingKit.framework both in my Test.framework and in TestExtras.app itself, so that I can run both TestPerson and the tests TestExtras was originally created for, a CompletionTest instance instantiated in MainMenu.nib, at the same time. It worked! –Although the failure of the CompletionTest tests meant that the application quit immediately.
I’m pretty happy with this, so it’s time to try it out for real.