This article is a revision of a previous article I wrote about unit testing with XCode.

I describe the steps carried to setup a test target long after a project has been created, so initially the test target will lack most of what’s needed to operate correctly (e.g frameworks, libraries and source files)

Setting up may take up to a few hours.

Creating a test target isn’t a big deal (just go to the project panel, add a new target and follow the steps).

I expect tests to run every time I try to build/run the main target. If the tests won’t pass I’d rather not fire up the simulator.

By default, the test target is not setup to work this way. Maybe it makes sense (after all, how does it know which target to depend on).

  1. Go to project panel => build phases ; add the test target under target dependencies.
  2. In the project panel, open ‘build settings’ for the test target, search for and tick ‘Test After Build’.
Note: You can also edit the scheme for the main target; under ‘testing’, add the test target. However doing it this way won’t action tests every time you run the application; you’d have to select the test action instead of run (top-left of xcode window, press and hold the ‘run’ button).
Up to ‘housekeeping’, the steps described below are likely necessary. Try to build before/after every step and check build messages to help you move on.

1. Adding source files

Maybe the fastest way to add your .m files: go to Build Phases and scroll to ‘source files’, then press add. type *.m as search filter. If you have many groups you may need to do this a few times to include all the required files.

2. Disable/Enable Automated reference counting.

In your test target, under build settings, search for ‘Reference counting’ and tick/untick “Objective-C Automatic Reference Counting”

3. Replace/Edit precompiled headers

In build settings, search for ‘pch’. If possible I just copy the *.pch from my main target settings to the test target settings.

4. Add the required frameworks & libraries

Most of this should be copied from your main target. Opening the assistant editor so you can compare/check both targets at once is useful (see build phases > link binary with libraries).

If you miss a library it will result in countless unresolved dependencies so it’s easy to figure.

5. List additional headers

If you’re pointing at additional headers in build settings, ideally you can share definitions by declaring them in the project’s (not the target’s) build settings – target-specific entries can be overwritten using $(inherited).

Housekeeping

Keep your framework/library references tidy: Checking the list of frameworks/libraries included in your project (there may be some in several places) may be a good idea as (harmless) duplicates may arise.

With frameworks/libraries, getting ‘red files’ is not rare. In many cases this doesn’t mean anything is actually broken (sigh…)

Remove unused files: remove files created by the wizard, if unused (e.g. precompiled headers)

Rename/Regroup: Renaming/Regrouping may cause references to break and need further editing. It’s a bit fidgety so you’ve been warned.

I like using generic names for my source folders (e.g. not MyApp Tests/ , just test/ ) and certain files (info.plist instead of MyAppTests-Info.plist). Renaming the info.plist will require editing in build settings etc… so maybe it’s easier to leave things as they are (XCode can help you rename project items).

Caveats

Beware that some classes in related libraries may rebuild after setting up the test suite; if old files were lingering in the system this may cause errors and confusion. Clean the build if things start looking weird.