Are unit tests worth an effort on iOS?

Nowadays I have such feeling that iOS developers, and in general speaking mobile programmers, don’t write unit tests of any kind. When I asked few of them „why?” they answered:

  • „Because it is time-consuming”
  • „I don’t know where to start”
  • „Mobile apps are so small there is nothing to test” – my favorite.

The question is, are those apps really so small? Take Facebook, Skype, AppStore app for example and ask yourself „Are they so small?”. The answer is simple – no, they are not.


Advantages of unit tests

I need to confess, I was one of such guy. Luckily my opinion about tests has dramatically changed because I had tried to write some! What has changed in my mind? I’ve noticed tests are an essential key to achieving cleaner code.

Object-oriented programming is all about dependencies. By dependencies, I mean the way how classes are connected with each other. While writing one, single test case, you want to test specific part of your system. It is easy to track if your class is doing too much. That means you need to split it to two separate classes. That means you are closer to preserve Single Responsibility Principle (I’m going to clarify SRP in next articles). Preserving SOLID (SRP is part of SOLID Principles) leads to less fragile code.

Moreover, I can only imagine the fear when developers want to change something inside a class or method and they don’t have tests. „Would that change be a start of a butterfly effect?” – they may ask.

Where TDD could not fit?

You can think now „Enough. I know. TDD is a blessing, but I need to be realist. Tests are time-consuming …”. I’ll say something you didn’t expect to read here. TDD is needless in some kind of apps. Imagine you work for an interactive agency and your duty is to write an application which will be used in a marketing campaign. Dates of start and end are fixed (start and end dates of the campaign, not developing process). If the application will be available on market ONLY for a short amount of time and you are for 100% sure it will never be changed or maintained you are free to leave tests. However, it happens once in a blue moon.

Do tests slow you down?

Jason Gorman has done some experiment how TDD and non-TDD practices are related with time. What has he done? The task was to write Roman Numerals converter. One iteration contained writing fully functional converter once with TDD and once without it. After he wrote code with TDD he took a break for some time to forget about what he had written and came back later to write it again, this time without tests. Jason did three iteration passes. What were his conclusions? He has noticed that in every iteration code written with TDD took less time, but (!) „he felt it was slower”.


What can you test?

What could we test in our mobile application? Most of them has some login system. How login flow can looks like:

  1. User writes his e-mail and password
  2. The app validates e-mail format
  3. The app validates password format (capital letters, number and so on)
  4. The app sends request to a server
  5. The app receives a response from the server
  6. The app parses the response
  7. The app displays a message with success or failure.

What can we test here? To be honest – everything 😉 . Under one condition… Login process should be separated to classes and not be done only in a single controller.

How to split classes?

Here you have my proposition how classes and their duties can be split:

  • LoginRequestValidator – to validate how password and e-mail look like (in my opinion having validation in Controller or inside a View is a big mistake)
  • LoginRequestFactory – to confirm if JSON request which app needs to send to the server is in right format
  • APIConnectionSystem – to send API requests in general (usually I have such class in my project and it’s a wrapper for AFNetworking)
  • LoginResponseParser – to parse JSON which came from a server
  • LoginMessageFactory – to create a proper message to the user based on error or success code.

Now you can test everything individually. There’s even more… Assume you need to change UI of a login screen. You can change it and you will not affect any of business logic. For example checking e-mail and password format. Awesome! :)

Give it a try!

I hope you are same excited as I’m ;). I really encourage you to play with TDD. In my career, it was a big step to increase my level of developing skills and make my code better. I would like to hear what do you think about tests on mobile. Are they profitable? Do you practice it? Have you tried? Feel free to leave a comment below.

Don’t forget to share this article.

You Might Also Like

  • Michal

    Out of curiosity, if you want to test an object in Objective-C/Swift with dependencies, do you create a protocol for each of these dependencies and implement it in a concrete mock class ?

    • Usually, I use mocks from OCMockito (https://github.com/jonreid/OCMockito). When I have a class which uses blocks as callback I use stubs ( extend a class or implement protocol for test target ). I’ll describe that more in-depth in next 2 articles 😉

  • Michał

    Great. That is my approach too. I think that the bad thing is that Unit Testing is usually taught and naturally connected to dependency injection with interfaces/protocols which bloats the code, while it can be done with good testing libraries in dynamic languages.

    I even asked a question to see if there’s any difference, because many people do it (create a protocol for each object)

    http://stackoverflow.com/questions/29700630/why-is-mocking-with-di-better-than-mocking-objects-in-objective-c

    With no answer :)