Why is it important to write test classes and methods?
“Ready, fire, aim: the fast approach to software development. Ready, aim, aim, aim, aim: the slow approach to software development.” — Anonymous
In computer programming, a unit refers to the smallest testable part of your code. This can be either your entire module, a single function or even the state of an object’s instance variable.
When you build and run your Swift code, you are testing your code from a whole or a macro perspective. Unit Test allows you to perform a test from a micro perspective so you can ensure that the individual components are functioning as expected.
Surprisingly, a lot of iOS developers choose not to write unit tests for various reasons including the lack of understanding or unawareness of advantages associated with Unit Testing in iOS development.
I was guilty of not using Unit Tests myself for a long time. However, I must say that once I started implementing unit tests, I wouldn’t approach iOS development otherwise.
From my experience, the following are some of the biggest reasons to include Unit Tests:
1. Testing the logic as you code.
“If builders built buildings the way programmers wrote programs, then the first woodpecker that came along wound destroy civilization.” — Gerald Weinberg
The approach I use is to write Unit Tests in parallel to writing my code. As an example, if I write a function in my main code, I also write a test case right after and test that function before writing another line of code. This not only helps me determine if that function or that method is working as expected, it also allows me to move on confidently.
2. Reduce the amount of bugs.
“There are two ways to write error-free programs; only the third one works.” — Alan J. Perlis
When you test as you code, you are literally testing for bugs in a module that you just wrote. When you call that module in your main code, it had already been pre-screened for bugs. As a result, only the clean and tested methods will be called in your main code. This significantly reduces the amount of bugs in your overall application.
3. Save debugging time.
“Deleted code is debugged code.” — Jeff Sickel
Similar to the previous point, the method is already debugged before being called in the main code. In short, you are bug proofing all your methods. If debugging is required for the main code, you would have the liberty to skip all the functions and methods as they are already tested for. Think about the amount of debugging time that will be saved in the long run when compared to the time spent on writing Unit Tests.
4. Streamlining logic.
“Programming languages are all the same; you just need a logic.” – Joey O.
Choosing to write Unit Tests will force the developer to write a very modularized code. This will introduce a lot of moving parts that can be individually tested. All the logic can then be streamlined by connecting these units. This in turn will reduce the time spent on refactoring the code as any factoring or refactoring will have a sole focus on connections between such modules and never have to take a dive inside tested units.
6. Provide defense mechanism to your existing code against any new changes.
“One man’s crappy software is another man’s full time job.” — Jessica Gaston
In real world scenario, iOS development can turn into a collaborative effort. Anyone within the development team can make changes in repository, and without any error checks, it can potentially turn into nightmare. Wouldn’t it help to fire each and every test case when new changes are added to repo and get notified of any bugs or issues? With Unit Testing implemented, you can configure the bundle in such a way that all the tests are fired when changes are made to repo, and you can also be notified about the issues found. Unit Testing can be a huge savior in such cases.
7. Catches incorrect output even when compiler doesn’t throw an error.
“A good programmer is someone who always looks both ways before crossing a one-way street.” — Doug Linder
This is perhaps the most important reason. If your method is throwing out a logically incorrect output, chances are that Xcode wouldn’t catch that and your code will build and run successfully. As an example, if there is a logical mistake in your function and the output is 38 instead of 36, Xcode still considers your method as valid. Such logical errors are caught only through Unit Testing.
Remember, it is okay to fail but it is important to fail fast.
My next post will cover step-by-step tutorial to writing a unit test classes and methods.
In my 10 years of iOS development experience, I have developed and helped monetize apps in various categories. So let’s talk!