Update: Apple took this to heart, and improved the unit test template in Xcode 5 and greater.
Xcode 4 has a File Template Library for creating new files. It includes a unit test template called “Objective-C test case class.”
Don’t use it.
Wouldn’t you like your unit test development to go faster? Let me give you a better file template.
Apple’s template puts cruft in your project. Cruft slows you down.
What’s wrong with Apple’s unit test template? Depending on which version of Xcode 4 you’re using, the template can be unnecessarily complicated, due to a distinction between logic tests and application tests that no longer exists.
But the template’s description reveals an ongoing problem: “An Objective-C class containing an OCUnit test case with a header.” A header? What for?
Many people assume that in C-based languages, you always write classes using two files: a header, and an implementation. But while header files often contain the class declaration, that’s not really what header files are for: A header file holds information so it can be shared by more than one file. In other words, it’s not where you put any and all declarations. Hide any declarations you can inside implementation files.
For a test case class, what needs to be included by more than one file? Nothing. OCUnit uses reflection to discover classes that inherit from SenTestCase, and within those classes, methods whose names start with “test”. This is all done dynamically; there’s no need to put the test class declaration in a header file (much less any test method declarations).
By creating a header file when it’s not needed, Apple’s unit test template puts cruft in your project. That cruft will slow down your scanning of the project navigator. To add an instance variable to your test fixture, you’ll have to open another file. When you add a test method, you’ll be tempted to create an unnecessary method declaration. Cruft slows you down.
A better unit test template
So let’s cut the cruft. Here’s a better file template for creating test case classes: OCUnit test case. And here’s how I use it:
- Find the template: Look for the friendly green checkmark that makes it easy to find among the other templates.
- File name: Use the name of the class under test as the file name prefix, and “Test” as the suffix. For example, to test the class Foo, I’d create FooTest.
- Confirm the test plumbing: Add the new file to your unit test bundle, and run your unit tests right away. You should see a failure in “testExample”, which lets you know that everything is set up properly. Delete testExample.
- Add tests: Create new test methods directly in the @implementation, without declaring them in the @interface.
This reduces the number of files in my project, and lets me code faster.
Download my unit test template and see for yourself.
To go faster still, I use a code snippet to create new test methods. Subscribe by email, and you’ll receive that code snippet and two others that help me write unit tests even more quickly!
Thanks for the post. I had never looked into making my own file templates, but now that I see how easy it is I’m inspired to update some of the other non-test templates as well.
Great! Another thing I use even more than custom file templates is custom code snippets.
This is good stuff. I agree that the header files for unit tests only clutter your test suite. Thanks Jon!
Stumbled upon your website and glad I did. Using your template and OCHamcrest for my TDD now.
Going to watch your TDD flics soon and going to check out your code coverage implementations. Loving it!
Thanks, Edwin! Spread the word… :)
Seems that Apple listen to you in Xcode 5 : no more header for test classes. The next step might be to be able to add a test implementation file when creating a new object : like there is a tick box for “Also create xib file when creating a view controller”, a “create test file” would be nice.
Maybe submitting a radar for this would make add such a feature…