If you don’t know what some code should do, you can’t TDD it. A spike solution (a throwaway experiment) gives enough information to begin the TDD process. But now we’re faced with design decisions: What methods do we want? How should they be organized? How should they be accessed?
With Test Driven Development, the surprising answer is: it doesn’t matter that much, because it’s going to change anyway.
Using a hammer to drive in a screw. I mean, it works, kind of.
But if you use a tool in a way other than its intended purpose, you’ll be missing its most important benefits.
It’s kind of like that with Test Driven Development.
Is TDD about preventing bugs? That’s more of a side effect than a direct goal.
Is it about making a test suite? Well, kind of. But… no. Not really.
It’s one thing to say, “Do test driven development.” But practicing TDD requires a set of tricks — you need techniques to enable test driven development in your particular environment. It’s these techniques which I hope to pass on to you through a case study of building an iOS TDD sample app.
I’ve accumulated a treasure chest of TDD ideas over the years. These ideas are often not my own, but are other people’s ideas which I collect and curate. Some are about object-oriented design. Some are about working in Xcode and Objective-C. And some are particular to iOS development. I’ve collected many, and continue to gather new ones.
I’m building this TDD sample app so that you and I can browse through this treasure chest together. You may have tried test driven development and given up on it. Or maybe you’re still trying, but finding it frustratingly slow. The ideas we will explore together will help you break through to make headway in your TDD journey, so that you can experience the freedom and ease that comes from automated testing and clean code.
The results of my reader survey are in. The #1 request? Case studies of unit testing, with more complex examples. And that got me thinking about the next major direction to take this blog.
When I was first learning Test Driven Development, I didn’t really have any examples to look at. All I had were descriptions of TDD. I stubbornly believed that these descriptions showed a more effective way of programming, so I fought my way there through the School of Hard Knocks.
But you shouldn’t have to do the same.
Remember my iOS Model-View-Controller TDD screencast? Eric Baker took it a few extra steps with his own follow-up screencast, demonstrating:
There’s a lot of interesting stuff here. But I also want to acknowledge that this screencast changed my mind about dot notation. Yes, really!
What are your thoughts about ReactiveCocoa, Kiwi, or AppCode? Leave a comment below.
The UIViewController TDD screencast ended with all the code in the view controller. Unfortunately, this is where many iOS programmers leave things! Let’s TDD our way to something better…
In part 2, we pick up from there and TDD to extract a model class, which the controller observes. You’ll see it evolve into true Model-View-Controller, driven by unit tests.
In particular, you’ll see how to TDD:
Is TDD worth the extra effort? I got a reaction from one person who tried applying my tips.
Andy Dwelly began applying my TDD screencasts to his iOS coding. Here’s what he writes in Some notes on Test Driven Development:
At first progress was almost painfully slow.
Yup. It seems like there’s a lot to learn. The real barrier, I think, is that there is a lot to unlearn. And so, when you first get started with Test Driven Development, your productivity will take a big hit. This is normal! But if you’re willing to press through the learning curve, your productivity will increase again — in ways you may not have experienced before…
This screencast focuses on the question I get the most: “Do you do test-driven development for view controllers?” It’s clearly a roadblock for many people. This screencast should remove that roadblock.
It also answers the question, “Is it worth doing?”
February 26, 2016 Update: Read to the end for Git repo bonus!
TDD is a series of small steps. It can be difficult to grasp until you see those steps demonstrated.
That’s why I made this screencast. It was sparked by a Stack Overflow question that said, “All the examples of unit testing I read about seem to be extremely simple and trivial.” The question asks how to write unit tests for a piece of sample code that uses NSUserDefaults.
Chapter 1 starts off with a surprising answer to the question, “Why write unit tests?” Why, to make more money! It shows how the traditional handoff-to-QA form of testing comes from the waterfall model of development, and how the cost of fixing defects increases with each phase of the waterfall.
Chapter 2 lays out the principles of Test Driven Development: test first, writing “Just Barely Good Enough” code that satisfies the test, and refactoring. But it also describes an important principle from Extreme Programming: “Ya Ain’t Gonna Need It,” or YAGNI. Basically, code only what you need to. This keeps production code simple, and avoids wasting time writing code that won’t have any effect.
The book goes on to introduce unit testing by showing how one might write tests without a unit testing framework — the old-fashioned way! Then we get an overview of the more common tools. Finally, we hit the meat of the book: a full example of creating an iOS app using TDD, spanning five chapters.