Test-driven development: Does it work for iOS apps?
Short answer: Sure! Here‘s an example:
Yeah, that‘s a really old image, and no, you can't find this on the App Store anymore. But this was an app published by eBay. Here's the unit test coverage:
It was written almost entirely using TDD. Sometimes tests weren't written first (especially the code written by someone I couldn't mentor because I was away). But test first or test last, they got written.
“That‘s fine,” you may say, “but what benefit did they have?” If you‘ve never done TDD, you haven’t felt the empowerment it brings:
- Writing tests before writing production code shaped the interfaces, leading to better design.
- High test coverage let me refactor when the code needed it, leading to cleaner implementation.
Better design. Cleaner implementation. Think about it.
A bit more about that 92%:
- I left third-party code out of the coverage calculation. This goes for open source (such as JSON parsing) and internal code used in other eBay apps. You don't need to write unit tests for code you're not going to change.
- At one point, the coverage was as high as 95%. I felt quite good about that. But when I met Jens Nerup in person and shared this number, he asked me a challenging question: "What about the remaining 5%?" 100% coverage may not be attainable, but don't stop at an arbitrary number.
- Having high test coverage doesn't mean bugs weren't discovered. There weren't very many, but preventing bugs isn't a TDD goal. It's more like a side effect. Again, the goal is shaping interfaces and enabling bold refactoring. Design + implementation.
Preventing bugs isn't a TDD goal. It's more like a side effect.
iOS test-driven development isn’t a pipe dream. I continue to use TDD for major apps, and train iOS developers on those apps. TDD is my daily reality, and it can become yours.
Question: Have you used TDD to develop your apps, or any part of your apps? What were the ups & downs you experienced? Leave a comment below.
It seems to me like there might be some benefit in writing unit tests for third-party/open source code, for while you might not change the code, you might need to update to newer releases. If your code assumes certain semantics for that code and a new release changes the semantics, then there is a chance that your unit tests could detect this change. Just a thought.
Sure, I’d say there are two cases where you might write tests against third-party code:
– you don’t trust it, or
– you don’t understand it.
I’ve done the first for services that were developed specifically for one of our apps. So I wrote tests that verified various user stories. While I happened to write them using the same tools I use for unit testing, these are really acceptance tests written by the customer of the services (me).
The second I would call “exploratory testing.” Basically, the purpose isn’t to verify, but to reveal: “If I call this, then that, what do I get?”
Uncle bob calls recommends you test your assumptions of third party components, through unit tests. You use these “architecture” tests to protect yourself from version changes. Ie before switching to a new version of a third party API run your API tests.
Great article BTW
Interesting! I still wouldn’t include such tests in my coverage results, but point taken: Any time you adopt a new version of a library, you are changing the code.
The coverage wouldn’t make sense, you aren’t trying to cover the API, just protect yourself from someone else’s changes…
The second ones can also be called the learning tests.
Would you have access to third party source to even consider the code coverage.
95% is high but how do you ensure you bring others in this journey in a diplomatic manner. Enforcement makes you enemies I found it the hard way.
Open-source that’s not distributed in binary form (so you’d build it yourself) would be included in code coverage, unless you exclude it. And that’s what I do.
As you say, enforcement doesn’t work. I try to lead by example. It takes patience, because you have to establish a history of good deliveries before you’re take seriously.
How did you arrive at the “92% line coverage” stat, Jon?
I’m new to TDD, and I’m excited to find your easy-to-understand, practical tutorials on this site!
Jon already has a detailed post about this, actually:
You’re very welcome.