iOS: Setting Up Advanced Unit Testing – Take Two

As Jon Reid mentioned on my “Setting Up Advanced Unit Testing” article on iOS testing, OCHamcrest now has  better support for iOS. It creates an OCHamcrest framework for IOS that includes the patches needed for iOS. I can now simply add the framework to my project and add a few additional linker options (which are the same as for OCMock) to make it work.

This should makes it a bit easier to setup hamcrest on iOS. Unfortunately there is a new complication. For iOS I now have to use

#import <OCHamcrestIOS/OCHamcrestIOS.h>

instead of

#import <OCHamcrest/OCHamcrest.h>

I don’t like that. I don’t see why it has to use a different name.

My solution is to build my own static lib for OCHamcrest. That is quite easy and it is my recommended solution.

Initially I switched OCMock to a static library because I had some issue compiling OCMock with block support. It didn’t pick up the proper iOS version and I always ended up with a lib missing block support. So finally I copied all the OCMock source files to my project and created a static library.

The OCMock source now live inside my project in a folder called “Source Xternal/OCMock”. To create a static lib I added a new “static library” target to my project (in XCode, right click Targets and Add/New Target and then select static library) with the OCMock source files below “Source Xternal/OCMock”.  Next I added the new lib (libOCMock.a) to my unit test project by adding it to the “Linked Libraries” (Get Info/Linked Libraries on the unit test target). The last step was to add “Source Xternal” to the “Header Search Paths” in the build settings.

Since the source folder is named OCMock the usual #import will work without change, i.e.

#import <OCMock/OCMock.h>

I didn’t need to modify any #import statement. (Now it also picks up the proper settings to compile it with block support :-)).

I did the same with OCHamcrest. The only difference to the procedure used for OCMock was that I flattened the sources of OCHamcrest into a single folder “Source Xternal/OCHamcrest”. Now all header files are below OCHamcrest and I do not have to touch the hamcrest #imports. (The original source layout uses subfolder to group the files).

This also removed the unwanted “IOS” postfix. So I can simply use the common #import <OCHamcrest/OCHamcrest.h>.

Finally I also moved Google Toolbox for Mac stuff to my “Source Xternal” folder into “Source Xternal/GoogleToolbox” and created another static lib for it.

So my source layout now looks like this:

Source
...
Source Test
...
Source Xternal
Source Xternal/OCMock
Source Xternal/OCHamcrest
Source Xternal/GoogleToolbox

That’s straight forward and also improves the build on my continuous integration server as it now builds all my dependencies as part of my project with the same compiler settings.

Another nice side effect is, that the source of the libraries is not far away and I can easily look into it. From time to time I get strange error messages when compiling and sometimes it helps to take a look into the source of OCHamcrest.

I’m already using this layout for a while now and its definitely my recommendation!

Happy Testing!