Reader small image

You're reading from  Test-Driven iOS Development with Swift - Fourth Edition

Product typeBook
Published inApr 2022
PublisherPackt
ISBN-139781803232485
Edition4th Edition
Right arrow
Author (1)
Dr. Dominik Hauser
Dr. Dominik Hauser
author image
Dr. Dominik Hauser

Dr. Dominik Hauser is an iOS developer working for a small company in western Germany. In over 11 years as an iOS developer, he has worked on many different apps, both large and small. In his spare time, Dominik builds small (often silly) apps and explores how he can become a better iOS developer. He talks at conferences, writes books, and is active in the iOS community in general. His most successful open source component (in terms of stars) is a pull-to-refresh control for a table view that consists of an actual SpriteKit game. Before Dominik became an iOS developer, he was a physicist, researching the most powerful photon sources within our galaxy.
Read more about Dr. Dominik Hauser

Right arrow

Chapter 9: Test-Driven Input View in SwiftUI

In 2019, Apple introduced SwiftUI as a new way to build user interfaces for apps on Apple platforms. In contrast to user interfaces built with UIKit, SwiftUI views are a function of some kind of state. As a result, testing such views can be very easy. In a test, we would have to set the state and assert that the expected user interface elements are present.

Unfortunately, the engineers in charge at Apple believe that there is no value in testing user interfaces. They believe that to prove the user interface looks and works as expected, it's enough to run the app and check with your eyes. This might be true for an app as simple as the one we are building in this book. But, if you have a look in the App Store, you will find most of the apps (if not all) are way more complicated. Usually, apps consist of many views and some of them are only visible in some rare cases. Ensuring that those views work for all input values and environment...

Technical requirement

Adding the ViewInspector package

ViewInspector is an open source library that you can find on GitHub: https://github.com/nalexn/ViewInspector. To add it to our project, follow these steps:

  1. Select the File | Add Packages menu item in Xcode.
  2. Type into the search field the URL of the package, https://github.com/nalexn/ViewInspector:

Figure 9.1 – Add the ViewInspector package

Click Add Package.

  1. Xcode presents a new window in which we can set the target to which the package should be added. Select the ToDoTests target. Then click Add Package again.

The package is now added to the ToDoTests target and we can use it in our unit tests.

Using ViewInspector to test a simple view

The view we are going to build will be used to add new to-do items to the list of items. This means it needs input fields for all information a to-do item can hold. So, let's look into that aspect in the next subsections.

Adding a title text field

As always, we start with the test. Follow these steps to add a text field for the title of a to-do item to the input view:

  1. Select the ToDoTests group in the project navigator and add a Unit Test Case Class with the name ToDoItemInputViewTests. Remove the two template test methods.
  2. Import the ViewInspector library and the main target (ToDo) so that it is testable (@testable):
    // ToDoItemInputViewTests.swift
    import XCTest
    @testable import ToDo
    import ViewInspector
  3. Before we can write tests for a SwiftUI view, we first need to extend it with the Inspectable protocol from the ViewInspector library. Add the following line right above the test case class:
    // ToDoItemInputViewTests...

Testing button actions with ViewInspector

The user puts in the address for the to-do item. In the details view of an item, the app shows a map of that location. This means we need to convert the address of the item to a coordinate before we can add the item to the list. Apple provides a GeoCoder class for that task. We will write tests for fetching an address from a GeoCoder class in Chapter 10, Testing Networking Code.

In this chapter, we assume that we already have a class called APIClient that uses GeoCoder (or some similar service) to translate an address into a coordinate. In the test, we are going to use a mock object for that APIClient class. Follow these steps to add a protocol for the APIClient class and a mock conforming to that protocol:

  1. Select the ToDo group in the project navigator and add a new Swift file with the name APIClient.swift.
  2. Add the following protocol definition to that new file:
    // APIClient.swift
    protocol APIClientProtocol {
      func...

Summary

Testing SwiftUI code works a bit differently from testing UIKit code. One reason for this is that SwiftUI itself works completely differently. In addition, Apple doesn't provide a testing framework for SwiftUI code because they believe that user interface code should be tested with UITest.

I don't think that's true. UITest solve a different problem. I believe you should have access to both kinds of tests, and you should choose the right tool for the problem at hand.

Fortunately, with ViewInspector we have a powerful third-party solution that fills this gap. In this chapter, we added it as a SwiftUI package to the unit test target. We used the package to write unit tests for SwiftUI code and build an input view for to-do items following test-driven development.

This way, we learned how to add SwiftUI packages to test targets and how to use this specific SwiftUI package to write tests for things that aren't easily testable without it.

In the next...

Exercises

  1. Add more convenient methods in the extension of ToDoItemInputView in ToDoItemInputViewTests.swift to make the tests easier to read as we did for test_save_shouldCallDelegate(). What are the advantages of these helper methods? What are the disadvantages?
  2. When the user provides an address, but GeoCoder cannot find the coordinate to that address, the app should show an alert and ask the user if they still want to save the item. Go to the GitHub repository of ViewInspector (https://github.com/nalexn/ViewInspector) and find out how you can test the presentation of an alert. Then write the test that asserts that the alert is presented and implement that feature.
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Test-Driven iOS Development with Swift - Fourth Edition
Published in: Apr 2022Publisher: PacktISBN-13: 9781803232485
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Dr. Dominik Hauser

Dr. Dominik Hauser is an iOS developer working for a small company in western Germany. In over 11 years as an iOS developer, he has worked on many different apps, both large and small. In his spare time, Dominik builds small (often silly) apps and explores how he can become a better iOS developer. He talks at conferences, writes books, and is active in the iOS community in general. His most successful open source component (in terms of stars) is a pull-to-refresh control for a table view that consists of an actual SpriteKit game. Before Dominik became an iOS developer, he was a physicist, researching the most powerful photon sources within our galaxy.
Read more about Dr. Dominik Hauser