How to Write Unit Tests in Swift Using Xcode
Writing Unit Tests are as important as your application code. As a developer, we often ignore to write Unit Tests, because of a tight project deadline.
In this article, we will learn,
- What is Unit Testing?
- How to Include Unit Test Target to the Project?
- How to Run Unit Tests?
- How to Write Unit Tests in Swift Using Xcode?
What is Unit Testing?
- In computer programming, unit testing is a software testing method by which individual units of source code are tested to determine whether they are fit for use.
- Using unit testing, we verify our core functionality, common workflow, boundary conditions, etc.
- Unit tests are usually written by developers and can be written before, during and after development.
How to Include Unit Test Target to the Project?
A unit test target can be added to the project at 2 different times.
- During project creation, by selecting Include Unit Tests checkbox
- If the project is already created then, navigate to
File ➞ New ➞ Target
(or click the “+” sign from the project window) and search forUnit Testing Bundle
How to Run Unit Tests?
At this stage, we have a unit test target with the Swift file and plist. If you wish, you can add multiple unit test targets to the project.
There are three ways to run unit tests.
- To run all the unit tests, Go to the menu bar and select
Product ➞ Test
or use the keyboard shortcutCommand(⌘) + U
- Click the little arrow button in the Test Navigator (⌘6)
- Click the diamond button (♦) in the gutter.
To run an individual test, click the diamond button in front of the test method name in the gutter or in the Test navigator
When all the test executes successfully, you should see green checkmarks in the Test Navigator and Test Succeeded message on the Xcode window.
Tip: Run your last test again using keyboard shortcut:
⌃ Control + ⌥ Option + ⌘ Command + G
How to Write Unit Tests in Swift Using Xcode?
- Before writing any unit test, you must know what functionality or logic you need to test. Otherwise, you end up with too many test cases that are not really useful and wasting precious development time.
- The default unit test target template imports the testing framework, XCTest, and defines a
UnitTestExampleTests
subclass ofXCTestCase
, withsetUp()
,tearDown()
,testExample()
andtestPerformanceExample()
methods. - The
setUp()
&tearDown()
instance method will call before and after each test method respectively.
Note: To know more about
setUp()
andtearDown()
method read Apple’s official article on Understanding Setup and Teardown for Test Methods.
At this stage, we are ready to write our first test.
Unit Test #1
Add the following code to the end of UnitTestExampleTests
:
// UnitTestEampleTests.swiftimport XCTestfunc testSumOfTwoNumbers() { let num1 = 10
let num2 = 20
let sum = num1 + num2 XCTAssertEqual(sum, 30, "sum should be 30")
}
- A test method’s name always starts with the
test
, followed by a description of what it tests. - Here, we are verifying the value of
sum
variable usingXCTAssertEqual
— Asserts that two values are equal. - Run your test using the keyboard shortcut
⌘+U
to verify thesum
value. If the test case pass, then it will show a green checkmark in the Test Navigator.
Unit Test #2 — Accessing methods written in code
Suppose we have written the method in our project which will return a product of the two integer numbers. Now, we want to verify the output of that method thru the unit test.
Add the following code to the end of UnitTestExampleTests
:
// UnitTestEampleTests.swiftimport XCTest
@testable import UnitTestEamplefunc testProductOfTwoNumbers() { let vc = ViewController()
let product = vc.productOfTwoNumbers(num1: 2, num2: 3) XCTAssertEqual(product, 6, "product should be 6")
}
- To access your code into the UnitTest module, you have to use the keyword
@testable import
- Here, we are verifying the output of the method
productOfTwoNumbers
which is written into theViewController
class.
Unit Test #3 — Async method
So far we have learned how to write unit tests and how to access methods written in our main project. Now we’ll learn how to write a unit test for an async method (ex: network call)
Add the following code to the end of UnitTestExampleTests
:
// UnitTestEampleTests.swiftfunc testFetchTODOList() { let exp = expectation(description:"fetching to-do list from server")
let session: URLSession = URLSession(configuration: .default)
let url = URL(string: "https://jsonplaceholder.typicode.com/todos") session.dataTask(with: url!) { data, response, error in XCTAssertNil(error)
exp.fulfill() }.resume() waitForExpectations(timeout: 10.0) { (error) in
print(error?.localizedDescription ?? "error")
}}
This test checks that fetching to-do lists from the server returns expected output or not. To check the async method, we used XCTestExpectation
an object. Where we first define the expectation and wait for the desired time until expectation fulfills.
- First of all, we create an
expectation(description:)
which will return anXCTestExpectation
object, stored inexp
. Thedescription
parameter describes what you expect to happen. - Next, we call
waitForExpectation(timeout:handler:)
keeps the test running until all expectations are fulfilled, or thetimeout
interval ends, whichever happens first. - Finally, we call
exp.fulfill()
method when the result meets our expectations.
You can check out the full list of Apple’s XCTestAssertions
If you like this article, feel free to share it with your friend and leave me a comment. You can follow me on Twitter for more articles related to iOS development.
Thanks for reading! 👨🏼💻