iOS Unit Testing
A robust suite of unit tests acts as a safety harness, giving you courage to make bold changes. But there’s an art to making tests that give you useful information, while keeping the tests themselves readable & maintainable.
How to Succeed with Unit Testing for iOS
Success with iOS unit testing comes down to 3 factors:
XCTest is your primary tool. Learn how to control it. Learn its subtleties. And learn how its launch sequence affects your tests.
Typical iOS code is filled with implicit dependencies which get in the way of testability. We need ways to manage them, and replace them with substitutes or Test Doubles.
View controllers lie at the center of iOS coding. Just because it’s “UI” doesn’t mean we need UI tests. Unit tests give developers faster feedback, with greater control.
Managing Unit Test Cases
Test cases depend on their infrastructure. Let’s take a look at some of the ins & outs around XCTest, and how the framework interacts with your production code.
Controlling Dependencies using Test Doubles
Difficult dependencies: can’t live with them, can’t live without them. We need ways of putting such dependencies behind a wall, and replacing them during testing. Swift gives us various ways to do that.
Unit Testing Your View Controllers
The idea of unit testing view controllers may sound silly at first. Shouldn’t you use UI tests to test UI components? But if you can tame view controllers with unit tests, you’ll have a much better developer feedback loop.
iOS Unit Testing: The Definitive Guide
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.
Other iOS Unit Testing Articles
Here are other articles that aren’t listed in the groups above yet:
Jump-Start Your Team.
Unit Testing Workshop for iOS Developers
I’ve created a class that guides your team through my unit testing approach. It covers XCTest foundations, unit testing view controllers, and managing hard dependencies.
It contains what I’ve learned from applying a unit testing approach to iOS apps — skills I’ve been using for the last 9 years.
Good Unit Tests Are a Huge Advantage
Hi, I’m Jon Reid, the founder of this website and the consultancy Quality Coding, Inc. I create content about unit testing because it’s been so important for my journey as a developer.
When I first left small coding shops and entered the big leagues, I was stunned by how much code there was in a single app. Or even in a single module. One coded until it “works for me,” then pushed straight to the shared repository.
This led to a mountain of bugs. I mean it — the bug count formed a bell curve called a “mountain chart”. Bugs heaped up, unresolved, while developers worked. They continued to pour in while the find rate was greater than the fix rate. At some point, QA called it “good enough” and it shipped, even with hundreds of known issues.
In this environment, it was easy for complex code to become more complex. Fixing one problem often created another — but you wouldn’t know it for some time. Eventually, I saw there were sections of code the developers were afraid to touch. You never knew when you broke something.
Knowing You Broke Something, Right Away
The great thing about a strong suite of unit tests is they can check thousands of details for you. And unit tests are fast. You get the test results in seconds.
This combination of spread and speed is liberating. It means you no longer have to be afraid. And that means you can make changes boldly.
Why iOS Unit Testing?
But why should we have unit tests for iOS code, when most of the app is view controllers? Shouldn’t we use UI Tests for UI?
The thing is, they serve different purposes. UI simulate human touches, so they’re easy to understand. But testing the entire app, end-to-end, has big costs:
Test pieces of code
Test entire app as opaque monolith
Directly load a view controller
Navigate to a view controller
The big difference between the two is what they operate on. Apple’s UI Tests touch the app from the outside. As a result:
- They can’t work around parts that interfere with testing.
- They give slow feedback about generalities.
But unit tests call the app’s code from the inside:
- They can use Dependency Injection.
- They give fast feedback about specifics.
Unit tests can give you feedback as you code. This makes them a coding tool.
My Experience Is Your Gain
I’ve been working with unit tests on Apple platforms since 2001. Mac OS X was a big step forward, because it was based on NeXT technology. Then iOS grew out of that. I started working on iOS in 2010, applying my Mac unit testing experience. This was before Xcode had built-in support for unit testing.
So for the entire time I’ve been developing iOS apps, I’ve been unit testing. I can say: this stuff works.
To spread “the stuff” further, I’ve written a book. It’s called iOS Unit Testing by Example: XCTest Tips and Techniques Using Swift. I’m positive it will help you, because I refer to the book myself.
You’ve got this. If you’d like any help along the way, I’m here for you.
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!