Getting Started with Swift Unit Testing in Xcode
In this article you’ll learn what you need to start unit testing your Swift code in Xcode.
Adding a Unit Test Target to Your Xcode Project
To unit test your app, your Xcode project must have a unit test target. The easiest way to add a unit test target to your project is to select the Include Tests checkbox when you create the project. Selecting the checkbox creates targets for unit tests and UI tests.
To add a unit test target to an existing Xcode project, choose File > New > Target.
Select your app platform (iOS, macOS, watchOS, tvOS) from the top of the New Target Assistant. Select the Unit Testing Bundle target from the list of targets. You will have to scroll through a long list of application extension targets to find the test targets.
Adding a Unit Test Class to Your Xcode Project
When you create the unit test target, Xcode includes a unit test class file. It has the name AppNameTests.swift
, where AppName is the name of your project. Unless you have a really small project, you will have multiple unit test classes.
Choose File > New > File to add a new file to your project.
Select Unit Test Case Class from the list of file templates. Click the Next button.
Enter the name of the class in the Class text field. The subclass should be set to XCTestCase
, and the language should be set to Swift. Click the Next button.
Save the file inside the Tests folder. Make sure to select the checkbox for the unit test target.
Click the Create button to finish creating the unit test class.
The Initial Unit Test Class
Select the unit test class’s Swift file to open it. It should look similar to the following code:
import XCTest
@testable import Scrumdinger
class ScrumdingerTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
The first two lines of code import the XCTest framework, which is the framework Xcode uses for unit testing Swift code, and your app. You must use the @testable import
statement to give the unit test class access to your app’s code. If your app name has spaces in it, use the underscore character instead of spaces in the @testable import
call.
@testable import My_App_Name
Next comes the declaration of the unit test class. It inherits from XCTestCase
, the base class for Xcode’s unit test classes.
Finally comes the four empty test methods.
- The
setUpWithError
method gets called before running each test in the class. Put any setup code you need to run before each test in this method. - The
tearDownWithError
method gets called after each test runs. - The
testExample
method provides a shell for a unit test. You can delete this method. - The
textPerformanceExample
method provides a shell for a performance unit test. You can delete this method.
The throws
keyword means the test method throws an exception if the test fails.
Older versions of Xcode may not have the throws
keyword in the test methods. The setup and teardown methods may not have the WithError
part at the end.
XCTest Test Methods
Each unit test requires you to write a method for it. A unit test method has the following requirements:
- It must start with the word
test
. - It takes no arguments.
- It returns no value.
The following code shows the definition of a unit test method:
func testMyExample() throws {
}
In the test start by calling the code in your app that you want to test. Then make an assertion, which I talk about next.
XCTest Assertions
Each test needs at least one assertion, which determines whether or not the test passes. XCTest assertions start with XCTAssert
. If you start typing XCTAssert
, Xcode’s code completion should show you a list of all the available assertions, but the following are the most widely-used assertions:
XCTAssertNotNil
asserts a variable is not nil.XCTAssertTrue
asserts a condition is true.XCTAssertFalse
asserts a condition is false.XCTAssertEqual
asserts two values are equal.
The simplest way to write an assertion is to supply an expression.
XCTAssertTrue(temperature > 0)
But when you supply only the expression, all you get when a test fails is a message that the test failed. In this assertion example, when the assertion fails, you would like to know what the value of temperature
is. Supply an error message to report as the final argument in the assertion. Wrap the variable whose value you want to report using the following syntax:
\(variableName)
The following shows an improved assertion that the temperature is above 0.
XCTAssertTrue(temperature > 0, "The temperature should be
above 0. Temperature: \(temperature)")
Running Unit Tests
Xcode provides multiple ways to run your tests.
- Press Cmd-U to run all your tests.
- Run a unit test class’s tests from the Xcode editor by clicking the diamond-shaped button on the left side of the editor next to the test class name.
- Run a single test from Xcode’s editor by clicking the diamond-shaped button next to the test method.
- Press Cmd–6 to open the test navigator. Selecting the test target, a test class, or a test will make a small button appear on the right side of the navigator. Click the button to run the target’s tests, the class’s tests, or the single test, depending on what you selected.
Unit Testing Checklist
Use the following checklist to start unit testing your Swift code in Xcode:
- Create a unit test target by selecting the Include Tests checkbox when creating your Xcode project.
- Add unit test classes to the test target by choosing File > New > File.
- Import the XCTest framework in your unit test classes.
- Use the
@testable import
statement to give your unit test classes access to your app’s code. - Add test methods to your unit test classes.
- Test methods start with
test
, take no arguments, and return no value. - Add at least one XCTest assertion in your test methods.
- Press Cmd-U to run the tests.