Chris Eidhof

Becoming a better programmer: Test-Driven Development

As I’m enjoying programming again (and more so every week), I started to think consciously again about improving myself as a programmer. After a recommendation of breun I started reading Clean Code, which I can definitely recommend.

One of the things I have always felt bad about professionally is not doing Test-Driven Development. Back when I was programming Haskell a lot I did do a lot of type-driven development, which overlaps a bit: you write down your types and then try to implement it. However, in Objective-C the type system isn’t of much use (compared to Haskell), so I really had to do it: write tests.

Another really big motivation is that I took over a project from another developer. The project was huge, and there were no tests at all. I ended up breaking things multiple times without realizing it (and I only found out after deploying it to the testers). I pledged to myself to do better than that.

Before I set off to write some tests, I had to find a testing framework. There is a great community wiki on StackOverflow called iOS Tests/Specs TDD/BDD and Integration & Acceptance Testing, but it’s also a bit overwhelming.

I started out by using the built-in Unit Testing framework that’s provided by Apple (see: XCode Unit Testing Guide). However, writing unit tests is quite hard for GUI code. As I wanted to test a new UIView subclass that I was developing, I had to test things such as tapping and inspecting other views.

Then I stumbled upon KIF (again, after a recommendation from breun), an open source integration testing framework by Square. As advertised, it was easy to configure and set up, and I was writing tests very soon after that. For example, here’s a scenario that tests whether my view closes, and even when you haven’t used KIF before you can understand exactly what it does:

KIFTestScenario *scenario = [KIFTestScenario scenarioWithDescription:@"Test that the picker closes when tapped outside"];

[scenario addStep:[KIFTestStep stepToReset]];
[scenario addStep:[KIFTestStep stepToAppear]];
[scenario addStep:[KIFTestStep stepToWaitForViewWithAccessibilityLabel:pickerAccessibilityLabel]];
[scenario addStep:[KIFTestStep stepToTapViewWithAccessibilityLabel:@"Tap to close"]];
[scenario addStep:[KIFTestStep stepToWaitForAbsenceOfViewWithAccessibilityLabel:pickerAccessibilityLabel]];

So far, I’m quite happy with the combination of KIF and the built-in unit testing. I’ll try to apply it to more of my projects, and probably be a better programmer because of that. At least when other people will read my code they can use the tests as documentation to see what the code should do.



  1. chriseidhof posted this
I like you. You should follow me on Twitter.