Hey, today I would like to say a few words about my experiences with testing applications. It’s a compilation of what I’ve tried so far with tests through many languages and technologies but especially related to the ones from Apple.

First, I would like to introduce you to my theory called TOWT. It’s an acronym that stands for ‘Thousands Of Written Tests’. It’s probably a ‘theory’ that can be applied to any domain but is extremely clearly visible when it comes to unit testing. It is as simple as that - your approach to writing tests changes each thousand written tests. I saw that happening to many of my colleagues and also experienced that myself. This year it’s yet another thousand and I’m still doing it differently.

1st TOWT

It’s the beginning of writing tests, your goal would be to write tests for any code you face. This also means you know how to refactor a system under test to be testable in every aspect. In an object-oriented language such as Swift, you’ll also learn a lot about dependency injection. Another skill that you will need is how to prepare all kinds of different test doubles. You might however get tired of preparing doubles by yourself so you may want to look for some automation like Sourcery or equivalents of Android’s well-known Mockito.

2nd TOWT

In the second ‘chapter’ of your testing journey, the most important skill is to learn what and how should be tested. It is not possible without previous experience. First you need to implement almost all possible test scenarios and, what’s more important, maintain them for a longer time. From now on you need to think of tests not as a separate green field for writing code, but as an integral piece of a system codebase. You will answer questions such as

  • ‘Should this be tested?’ - for a possible over-testing, like third-party / SDK tests in your codebase
  • ‘Isn’t this test doing the same as some other one’ - for common pitfalls like assertions duplications
  • ‘Does this check help me at all?’ - for a kind of test that takes much more energy to write and maintain than the benefit it provides

3rd TOWT

You are now an expert in preparing a test for a piece of code. You consider so many different constraints when doing it. You can now make your testing codebase more prepared for changes over time. There are two main goals here:

  • maximize the independence of tests for changes in the system under test
  • optimize understanding of testing code when it’s first to read or maintained

You know that feeling when you implemented some change in the living codebase, it works perfectly when run and now … now it’s only tests to update? You trigger the test suite after all and it’s all blinking in red? Achieving these goals can be a game changer for all swearing words thrown in such situations. The most difficult question is how to do that. My answer so far is to introduce helpers and some simple rules of thumb. Sounds easy, but it requires a huge amount of self-discipline to avoid going the easy way when writing a test. These are simple examples:

  • If there is a complicated setup code, it’s worth extracting it to methods that would perfectly describe what you’re actually setting up and how.
  • If that mocking code can change over time, it’s even more important to extract it away from test code. That way it’s much easier to modify a method that is responsible for preparing some mock than a test itself.
  • If there are multiple very similar tests, it’s very much worth extracting some base test case as a separate method and only implementing specific calls of that method as test cases.
  • Try to have only one assertion for each test.
  • Always assert with the data that you’ve prepared in a setup phase, not enter it into the assertion directly.

This list is just an example, you can do whatever you believe would help, but you want to achieve these two goals I’ve mentioned.

4th TOWT

Indeed this ‘chapter’ is sort of a continuation of a previous one, however I decided to extract it as a ‘next level’ to emphasise the difference. Through so many lines of testing code that you’ve already written in your development career is there anything left that can blow your mind? Yes, it’s a different approach to writing tests. And two of them that play with each other perfectly are:

  • TDD - Test Driven Development
  • BDD - Behaviour Driven Development

I highly recommend you deep dive into these approaches. As a short introduction here:

  • TDD can help you to write code that suits perfectly all the scenarios
  • BDD approach can help you to define those scenarios.

For the iOS world, you can take a look at Quality Coding blog about TDD and try the Quick library for implementing BDD.

After all, what’s the most powerful is that these approaches put some enabling constraints on you. For instance, with BDD it’s much easier to consider all cases, extract some similar setup for all / some of them, and have great readability - all at the same time. TDD enforces you to define these logical scenarios before the actual code, which makes sure that the code would perfectly fit into the specification. You can use either one of them or both, but whatever way you’re gonna go it is a huge improvement in writing tests.

5th TOWT?

Silver bullet? Yep… It doesn’t exist and, of course, the story still doesn’t end here. As you can see there is no one way of writing a good test. It’s a result of experience in writing tests and surely not a kind of knowledge that you can learn from one article or either a book without practicing. The best thing about writing tests is that after yet another TOWT you’ll still see some improvements. I am very excited to look into this article in a few years to see what could be the next chapters for me! I’ll leave this ‘book’ empty here for now 🙂

Summary

One more thing that I would like to mention - there is this ‘first step’ in the testing world. Either for you, if you recently started your developer journey, or for your colleagues that you need to encourage for writing tests. If you need arguments I hope this story shows how far you can go with tests. From being just another code to write to becoming your technical partner and helper for driving your code by business requirements.

I hope you enjoyed the article. If you have any questions or want to talk about practical examples or elaborate a bit more on a particular TOWT please grab me via twitter.

Updated: