Article

Five Reasons To Write Unit Tests

It’s not as difficult as you may think

Josh Rondestvedt

December 1, 2021

Introduction

Writing unit tests can be intimidating for developers just starting their journey into the world of programming. Like most people, I was no different. I put off writing unit tests until I was in my second year of learning development. I wrote my first production app as an indie dev with zero tests. I was so concerned with building out features that I was blind to the advantages of unit tests. In fact, I would have probably saved myself time overall if I would have just written some tests because I would repeatably build and run the project on the simulator to verify my logic was working correctly.

This article isn’t going to be a how-to guide on how to get your project set up for unit tests. Instead, I hope I can change your perception to the importance of this topic.

This article will be through the lens of iOS development.

1 — Ensure code refactors don’t break existing functionality

Having unit tests brings peace of mind as you’re building out the project. Let’s say you need to fix a bug and it requires more changes to the codebase than originally expected. Once you’ve made your changes, you can run all your tests to ensure you didn’t break existing functionality elsewhere or introduce another bug. One good rule of thumb is to write a test or two for every bug you fix so you don’t have to worry about the functionality breaking again.

2 — Adds benefit when learning a codebase and expected behavior

When joining a project with a large codebase, it can be difficult and take time to get comfortable. Having tests that show the expected behavior and possible edge cases can help solidify your understanding of the project.

3 — Running the simulator less

When building out a new feature, the only way to test the logic is to run the project. Depending on your machine and the project size, this seemingly small amount of time can add up and cut into your efficiency. This has somewhat been eliminated with the introduction of SwiftUI’s live preview and Apple’s new M1 machines, but any amount of time saved is a good thing. If the feature is on the first screen, it may not seem like an issue but imagine testing a screen that’s buried in the view hierarchy.

4 — Encourages dependency injection

Dependency injection is an extremely important concept if you want to keep your code modular and testable. This topic is rather large and can be somewhat difficult to understand initially so I’m just going to touch on the basic concept. Let’s say you have a view and you need to pass in another class/protocol/enum to populate a few labels. Ideally, you would pass in this type through the initializer. This is dependency injection in its most simple form. To drive the point home, you are passing in a class/protocol/enum to this view because it depends on its values.

5 — Forces you to think about access control

When creating types, I initially mark the properties, methods, etc as private. This makes it clear to your colleagues that the functionality is only used within the type. If you need to read the contents externally, you can use private(set). Unfortunately, private properties and methods cannot be seen in your test target. There are some tricks you can use to retrieve private UI components, but that's for another article. You will need to find the right balance between access control and testing.

Some honesty

While getting started is rather trivial, I must be honest and say it can get rather difficult. Writing tests for asynchronous methods can be challenging and frustrating. Mocking networking services can also be tough if you’re somewhat new to development.

Writing tests is time consuming. Every hour spent on writing tests is one less hour spent on developing new features. Personally, I think it’s worth the trade-off. Users won’t care about your new features if your application keeps crashing from preventable bugs.

You shouldn’t strive for 100% code coverage. Start with writing tests for the core functionality of your application and slowly add as you go. Just like learning any technology, it gets easier the more you do it. Don’t overwhelm yourself with philosophies such as Test-Driven Development (TDD), just start with a few tests and go from there.

Summary

Once you get over that first hurdle and have a few tests in your project, you will start to see the benefits. Keep your first couple of tests extremely simple and I promise, it will get easier. If I’ve done my job correctly, you are excited to get started 🙂. Here’s an article on how to set up your existing project for unit tests. If you’re starting a new project, it’s as easy as ticking a checkbox. Remember, unit tests are important and should be a priority when building out projects. You don’t want to be the app that hard crashes because a method attempts to divide by zero 😉.

  • Josh Rondestvedt

    Software Engineer

    Josh Rondestvedt