XCTest. Test if UIButton is Connected And Has Action

In this XCTest tutorial, you will learn how to write a unit test that will test if UIButton is connected to @IBOutlet and has @IBAction assigned.

For this tutorial, I will create a Single View application project. I will use the default View Controller that XCode creates for all new projects and I will position on a View a single UIButton.

Create a New Xcode Project

I have created a new Xcode project with a Single View Controller in it. At the center of UIView, I have positioned a single UIButton and have created for this UIButton @IBOutlet and @IBAction. On the image below you can see how my View Controller looks after I have added a UIButton to it.

 

Test UIButton has IBAction

Create the XCTest Test Case Class

As a next step, I will create a new XCTest Test Case class and will update its default setUp() and tearDown() methods.

The setUp() method

The setUp() method is very simple. For me to be able to access UI elements in a View Controller I first need to instantiate the view controller and make it load the View by calling the loadViewIfNeeded() method.

override func setUp() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    sut = storyboard.instantiateViewController(withIdentifier: "ViewController") as? ViewController
    sut.loadViewIfNeeded()
}

The tearDown() method

In the tearDown() method I simply release resources.

override func tearDown() {
    sut = nil
}

Unit Test to Test of UIButton is Connected

Now it is the most important part. I will create a new test method to test if the UIButton is connected and if it has IBAction assigned to it.

func testIfLoginButtonHasActionAssigned() {
    
    //Check if Controller has UIButton property
    let loginButton: UIButton = sut.loginButton
    XCTAssertNotNil(loginButton, "View Controller does not have UIButton property")
    
    // Attempt Access UIButton Actions
    guard let loginButtonActions = loginButton.actions(forTarget: sut, forControlEvent: .touchUpInside) else {
        XCTFail("UIButton does not have actions assigned for Control Event .touchUpInside")
        return
    }
 
    // Assert UIButton has action with a method name
    XCTAssertTrue(loginButtonActions.contains("loginButtonTapped:"))

}

In the test method above I first check if View Controller has a UIButton property “loginButton“.

let loginButton: UIButton = sut.loginButton

When I have a reference to a button I can read all actions assigned to this button.

guard let loginButtonActions = loginButton.actions(forTarget: sut, forControlEvent: .touchUpInside) else { 
XCTFail("UIButton does not have actions assigned for Control Event .touchUpInside") 
return 
}

Now when I have an array of button actions I can check if there are any actions at all or I can check if it contains a specific action(method name).

XCTAssertTrue(loginButtonActions.contains("loginButtonTapped:"))

Complete Test Case Class

import XCTest
@testable import Test_IF_UIButton_IS_Connected

class Test_IF_UIButton_IS_ConnectedTests: XCTestCase {
    
    var sut: ViewController!
    
    override func setUp() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        sut = storyboard.instantiateViewController(withIdentifier: "ViewController") as? ViewController
        sut.loadViewIfNeeded()
    }
    
    override func tearDown() {
        sut = nil
    }
    
    func testIfLoginButtonHasActionAssigned() {
        let loginButton: UIButton = sut.loginButton
        
        guard let loginButtonActions = loginButton.actions(forTarget: sut, forControlEvent: .touchUpInside) else {
            XCTFail("UIButton does not have actions assigned for Control Event .touchUpInside")
            return
        }

        XCTAssertTrue(loginButtonActions.contains("loginButtonTapped:"))
    }
}

I hope this tutorial will be of some value to you. Have a look at other XCTest unit testing tutorials on this blog. You might find many other interesting tutorials.

Happy unit testing 🙋🏻‍♂️

1 Comment on "XCTest. Test if UIButton is Connected And Has Action"

Leave a Reply

Your email address will not be published. Required fields are marked *