Make a Test Helper for Button Taps

Tapping buttons is something we’ll do quite a bit when unit testing view controllers. But sendActions(for: .touchUpInside) isn’t very descriptive. We can improve the readability of our tests by extracting a helper to tap UIButtons.

Putting test helpers in a separate file makes it easier to find them. In the Project Navigator, select the ButtonTapTests group and press -N to make a new file. Select Swift File, name it TestHelpers.swift, and set its target to the test target. Give it the following code:

ButtonTap/ButtonTapTests/TestHelpers.swift
 import​ ​UIKit
 
 func​ ​tap​(_ button: ​UIButton​) {
  button.​sendActions​(for: .touchUpInside)
 }

Change the test to use this new helper:

ButtonTap/ButtonTapTests/ViewControllerTests.swift
 tap​(sut.button)

Run the tests and confirm that the console output says Button was tapped.

UIBarButtonItems aren’t UIControls, so we can’t call sendActions(for:) on them. We can make a separate helper for them. We won’t use it until the example in Chapter 17, Unleash the Power of Refactoring, where we’ll work through an example with a UIBarButtonItem. But for reference, here’s a test helper to tap them:

ButtonTap/ButtonTapTests/TestHelpers.swift
 func​ ​tap​(_ button: ​UIBarButtonItem​) {
  _ = button.target?.​perform​(button.action, with: ​nil​)
 }

Swift’s function overloading lets us support the common abstraction of tap(_:) for two types. This also means that if we change a button type from UIButton to UIBarButton, the test code can stay the same.

images/aside-icons/tip.png

Extract test helpers to make your tests more readable. They’ll also make the tests less fragile.