(While I’m busy finishing my book, here’s a guest post from Ellie Coverdale. Take it away, Ellie… —Jon)
Unit testing is an important part of establishing the correct functionality of the individual units of a single software program. Software can get deeply complex, with all sorts of potential elements making life more difficult for you as you try to get a picture of the program as a whole. The more complex the software, the more complex the units and, often, the more of them there are to have to contend with as you go through your development process.
By isolating components of your software you can put together a checklist that lets you establish what works and what doesn’t in your application. In essence, a unit test is not a particularly complex concept. In fact, it’s all about clarity and simplicity. However, architecting a unit test has a certain complexity to it that needs to be cut through for you to succeed in your goal. So, with all of that said, let’s look at three simple steps to constructing iOS unit tests with clarity and efficiency.
1. Make Sure to Isolate the Components
A strong, well-structured unit test will always consist of thorough, isolated elemental tests. Your program likely consists of many, many different components, each with their own complexity and set of difficulties assigned to them. The whole point of a unit test is to ensure that no man, or rather component, gets left behind, making isolation important.
Going through your application bit by bit and slowly dealing with each component one by one can seem a fairly tedious way to test anything, but it’s structured like that for a reason. All of the components in a unit are liable to go wrong, as things do in software development. “When you can really hold each component of each unit of your software accountable for how it’s all functioning, you put yourself in a great position to never have to experience one of those dreaded mystery problems,” says Howard Cole, tech writer at Essay Roo and Paper Fellows. You ought to, whenever possible, have a file that corresponds to each of the components that contains all of the tests. That way if you see a component without a test file, you know that it’s a liability.
2. Do the Same with Behaviors
As if you hadn’t had enough isolation for one article, there’s more to come. So, you’ve isolated your component as part of your unit test and there’s now a test file linked to it. Good job, you have the framework for a really well architected unit test. So now you need to start actually performing the test.
What you’re testing for is behavior, meaning how your components each behave as they are tested one by one. If they behave as desired/expected, then they pass. If any of the properties wind up in the wrong position, then you have a failed test on your hands. I always find that a failed test is for some reason more reassuring, at this individual level at least, than a completely flawless set of results. There’s something eerie about everything be perfectly correct on the first set of tests. Luckily, or unluckily if you don’t share my sense of paranoia, this is almost never the case. So, when your problems do appear you want to have your behaviors all neatly organized so you can identify the problematic components with ease.
3. Include Negative Test Outcomes
Really all that this is saying is that you need to be thorough about testing your system. “Testing for an outcome of a single component’s functionality isn’t as simple as ‘yes’ or ‘no’. It’s more a question of ‘no but…’ or ‘no and…’. You need to make sure that all possible outcomes, and the reason for each of them, are listed in the case file,” says Harrison Long, developer at Australian Help and State of Writing. Having all of your negative test outcomes is a great way to have the most complete understanding possible.
Ah software development, so…tedious. But also deeply satisfying, with so many smart ways to find the best possible results. Hopefully this 3-point checklist will give you a great opportunity to structure your best possible unit test and ensure there aren’t any sneaky errors.
(Jon here again. You may be wondering, “But how do we do this for iOS code?” If you have questions about about how to apply Ellie’s 3-point approach, please ask below. Or, maybe you have some good examples about how you’ve done any one of these 3 things. Discuss away…)