UI Testing in Swift

I. Why use UI Testing?

1. Automates manual testing 🤖

  • When we test an app, we always repeat the same process to test that we have not broken anything. We can achieve this with a battery of tests that do the same work as manual testing.

2. Abundant logic in the presentation layer 🌅

  • The more UI Logic we have, the more we have to test

3. Saves time ⌚️

  • With a battery of ui-tests we can repeat the same manual testing every time we want in much less time.

II. What can we test?

  • Buttons
  • Refresh tables
  • Type text
  • Slide sliders
  • Check Navigation Bar titles
  • Push and pull View Controllers
  • Reorder Cells
  • And so on..

You can check this UI-Testing-Cheatsheet for more information.

III. How can we test properly?

1. Architectures that help to separate logic from presentation 🏠.

  • When we talk about MVC we all know that it isn’t very testable because interactions between the view and the controller are very attached.
  • We can achieve better testability with a better distribution, using for example a MVVM or VIPER architecture. You can check this awesome post for more information iOS Architecture Patterns.

2. Dependency injection 💉

  • This software design pattern allows the choice of a component to be made at a run-time rather than compile time, with the purpose of replace production code with Test Doubles.
  • An example of Dependency Injection would be something like this ServiceLocator:

Here I am using a VIPER Architecture so we have to assemble all corresponding modules to provide a root view controller where all works properly.

To change the data source in real-time we need to configure the new data source and reassemble the root view controller to do the magic:

3. Frameworks 📦

KIF

Is a useful framework that makes testing easy by leveraging the accessibility attributes for those with visual disabilities. The magic of KIF is that it allows you to drive your UI from your unit tests and reap all the advantages of testing in-process.

If we are using swift, we will have to do a previous configuration because of is written in Objective C, see documentation for more details.

Here is an example:

Nimble

Is a Matcher framework that makes assertions more readable and intuitive:

IV. Practice!

  • At this point we have to know which tools are being used for UI Testing. Moreover, we are able to replace production code for Test Doubles, that is possible thanks to a good architecture. With all of that, let’s do some practice.

Project Structure

Let’s get acquainted with our app which we are going to test later.

Is composed by 2 view controllers:

  • CharactersViewController: is the main view controller and is showing a list of GOT characters.
  • CharacterDetailVC: Shows the detail information of a character.

CharactersVC Tests

Aux Methods

There are some auxiliar methods that we are going to use for Testing.

To change production code we have 2 methods givenThereAreCharacters and givenThereAreNoCharacters that change the api client. And to make this changes applied we have to use openCharactersVC to change dynamically the rootViewController.

Other methods that could help us testing are numberOfElementesInCharactersTableView and getRandomCellNumberInTableViewBounds. The first one is used to count the elements in the table view, and the other to generate a random number between these elements.

Tests

Let’s write our first test:

With this simple test were are checking wether elements are correctly dequeued in the table view or not, comparing our apiclient characters with the table view characters.

To check that we are showing the characters properly in the detail controller we use this function:

CharacterDetailVC Tests

Aux Methods

First we have to write our auxiliar method to open a particular character in the detailVC:

Tests

Finally we will write some tests for CharactersDetailVC:

Final Results

After writing some test we will have a battery of them, and the results should be something like this:

We will not have to repeat this process manually anymore 🎉.

V. Where to go from here

Check the entire project on github, see all the configurations and Frameworks used.

Try to write some UI tests on your own.

Create your own project and do some stuff following this structure!

VI. Attributions