iOS Test-Driven Development
Writing unit tests after production code is hard. And such tests may only confirm your biases. Test-driven development shapes production code in response to tests, in an evolutionary process. It’s about working with continuous feedback.
Test-driven development (TDD) is well-documented elsewhere, but the examples are mostly in Java, and are GUI-agnostic. At Quality Coding, you’ll not only discover examples in Swift and Objective-C; you’ll also learn how TDD works within iOS.
You’re already a seasoned iOS developer. Why should you learn a new way of programming? Test-driven development looks weird, even backwards. Does it even apply to iOS development? You bet it does. Come learn why it’s worth changing your development style.
What are the actual steps and techniques involved with iOS test-driven development?
Most of what I wrote about this goes back to the early days of Quality Coding, so also check out the Examples in Objective-C group further down.
Examples in Objective-C
I’ll begin updating my original examples to make them more accessible to Swift programmers. But don’t be afraid to look at my Objective-C examples.
TDD Workshop for iOS Developers
Learn iOS test-driven development from Jon Reid, author of iOS Unit Testing by Example, who has been practicing TDD on Apple platforms for 20 years.
Other iOS TDD Articles
Here are other articles that aren’t listed in the groups above yet:
To do iOS test-driven development, you need to know how to write iOS unit tests.
My book iOS Unit Testing by Example: XCTest Tips and Techniques Using Swift is the definitive guide to unit testing iOS apps. It covers foundational tools and skills, testing specific behaviors of iOS apps, and how to use the fast feedback from your tests.
Test-Driven Development for iOS: Alien, or Natural?
Hi, I’m Jon Reid, the founder of this website and the consultancy Quality Coding, Inc. Back in 2001, I was looking for safer, saner ways to code. I came across Extreme Programming, a set of practices that predates “agile” as we know it today. Test-driven development (TDD) is one of these practices.
Here’s a simple explanation of the TDD workflow. We repeat three steps:
- Write a single unit test that fails.
- Write the most obvious production code that passes the test.
- Now that it works, refactor: clean up both production code and test code.
Repeat these three steps over and over. There’s a lot of nuance in how these steps work, what each step is for, and the purpose of each transition to the next step. But these three steps are the essence of TDD.
iOS has a cultural problem
On the face of it, there’s nothing special about test-driven development for iOS. You still do these same three TDD steps as anyone else. But when we’re learning to work with Apple’s frameworks, we usually learn by trying sample code. And the fact is, very little iOS sample code is written to show test-driven development. It’s not even written to show testable code. Actually, you’re lucky if you see any examples of tests.
Some of this is due to the nature of sample code. Much of it comes straight from internal Apple culture. I’ve been on the inside. Testable code is rarely a concern there, much less test-driven development. There are people and teams inside Apple trying to change that, but changing any culture is a long road.
That’s why I wrote iOS Unit Testing by Example. My initial goal was to write a book about TDD for iOS. But after a survey, I found the biggest barrier to TDD on iOS wasn’t necessarily the TDD itself. It was the lack of knowing how to write unit tests for ordinary iOS code. So I pivoted, and wrote a book hoping to address that problem.
Because you can write unit tests for iOS without unusual patterns. Sure, you can apply “functional core, imperative shell” style which makes it much simpler to write tests. But this is alien to most iOS developers. I wanted to show that you don’t need to adopt advanced architecture before testing, or doing TDD.
Test-after isn’t good enough
You may ask, isn’t it good enough to write unit tests after production code? The answer is no.
Folks who live by test-after focus on two separate goals: First they write all the production code changes they want to commit. Then they write tests, hoping to prevent any breaking changes that may come later. The goals are “make it work,” then “add test coverage.”
The goals for test-driven development are rather different. The three steps lead to different results. Adding tests isn’t a goal, it’s a means to a different end: refactoring.
Refactoring means we change the design of the code. As long as the tests pass, we can discover whatever shapes make sense for the code. With test-after tests, it’s easy to write tests that lock down the production code. But the TDD mentality is to encourage changes to the code.
If I write my tests after, I'm likely to couple them to the existing code structure and then they guard against change instead of against failure. I want change. — Tim Ottinger
I’m your local guide for iOS TDD
I started TDD in 2001, working in C++ on Mac and Window. In 2005 I began to apply it to Objective-C. Then I got my first iOS job in 2010. Continuing test-driven development when I started iOS was never a question for me. I didn’t know any other way.
Perhaps that makes me a native of the iOS TDD land, instead of an immigrant. An immigrant—and we need more of these!—enters a new land and has to relearn everything. New language, new culture.
When you move to a new land, one of the best ways to get acclimated is to get a local guide. Someone who is intimately familiar with the culture, because it’s their own culture. For test-driven development in iOS, I am one of those guides.
As Apple technology continues to shift, we’re all learning. Every new piece makes us all beginners, and there are many good sites about the Swift programming language. But if you’re looking for guidance on TDD for iOS, I can provide the training you need.
Join Us & Never Miss an Article!
Want to make sure you get notified when I release my next article or video? Then sign up here to join my list of Quality Coding Insiders. You’ll receive email notifications whenever I release new content. Plus, you’ll get access to the test-oriented code snippets I use every day!