Build Automation With XCode 4.3, KIF and Jenkins
UPDATE: As pointed to me in this commment, sym links aren’t necessary for Waxsim anymore. Check Jonathan Penn’s fork on github.
After coming back from my holidays in China - which were awesome - I had no downtime at ThoughtWorks and started at a brand new client/project - a much needed change from what I had been working on lately.
It’s an iOS project, more specifically an iPad app and that’s pretty much all I can tell you about it. I will however tell you how my first few days in the project have been so far.
Being a brand new project I wanted to get our CI environment up and running as fast as possible - after all the project has only a couple of tests now. For context, here’s our setup:
- XCode 4.3
- GHUnit (I’m not gonna talk too much about it since this was the easy part - their docs are pretty decent)
- KIF (for UI tests)
- Jenkins
- WaxSim (Hack to get the iPhone Simulator to run on the command line)
In most environments I had worked so far - Java, Ruby, Clojure etc.. - running acceptance tests from the command line is a given and so is integrating that into your build system.
Well, that’s just not the case with iOS projects. These tasks can be a real pain and take a while to complete. Here’s what I had to do:
On your development Mac
I’m assuming here you have an XCode project with at least one KIF test and that it builds successfully from the GUI, when you hit play. Now we can move on to run the tests from the command line.
This is the script I’m using to run my KIF tests. I call it RunKIF.sh and will walk you through it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
You’ll notice there are mainly two things happening in this script:
- It runs xcodebuild to build the target against which your tests will run
- uses WaxSim to finally run your tests
To get the building step to work, despite what KIF’s documentation DOESN’T tell you, you need to add KIF as a target dependency to your KIF Tests target. This SO thread can walk you through it.
Now on to the fun stuff!
For some reason I didn’t have the time to dig into, WaxSim seems to expect XCode to be under /Developer/ on your Mac.
The problem is that since Apple started distributing Xcode through the AppStore, it now lives under /Applications/Xcode.app/Contents/Developer/. Bam! This can cause all sorts of issues when building both WaxSim and your project. So if you see weird error messages complaining about not being able to find DevToolsFoundation.framework and the like, these sym links will probably fix things for you:
1 2 3 4 5 6 7 8 | |
I know, right? Moving on.
By now you should be able to successfully run RunKIF.sh and get meaningful results from your test. Let’s configure our CI server now, shall we?
On your CI Mac
Depending on which state your build box is, you might need to create the same sym links I created in the previous section. So ssh into your build box and try to build your project from the command line:
1
| |
This time I’ll assume you already have Jenkins installed and running.
Your Jenkins server is probably running as the jenkins user. You need to change that. Jenkins has to be running within a Desktop session - that’s a requirement from WaxSim. It needs an active desktop session in order to launch the simulator - and thus needs to run as a user who can login to your CI Mac.
If you installed Jenkins using Homebrew, here’s a plist you can use to specify which user jenkins should run as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Then load the new plist:
1
| |
Don’t forget to enable automatic login on the CI Mac for the user Jenkins is using. Check this article to learn how to do it.
Now we’re mostly done. Just go ahead and configure your project.
Add a build step of the type Execute Shell and provide sh RunKIF.sh as the command string. Trigger your build and everything should work as expected.
Final thoughts
Once I actually got these steps together to write this post, it didn’t look like much. But the amount of time I wasted finding out what had to be done to actually make this work is just insane.
I’m shocked at how much behind iOS development tools seem to be. It just shouldn’t take this much effort and time only to get some UI tests automated. So far I’m disappointed with the tooling around the Apple ecosystem and I really hope this improves sooner rather than later.