Get Started with Unit Testing in Swift

Understanding how the XCTests framework is used to do Unit testing in Swift

Nikhil Vinod
5 min readNov 20, 2022
Photo by John Schnobrich on Unsplash

You are completely new to XCTests? You know I got you covered. I will cover the basics of XCTests with examples.

Basics

Unit Tests — They are automated ways to test parts of code. The feedbacks are quick and straightforward.

Implementing Unit Test Case
To get the hang of Unit Testing, we will start with an elementary example. First, we will write a function that returns the total numbers count in an inputted string.
For this, we will create a new project. And check the Include Tests option.

Once the project setup is done, we will explore the NVExampleTest file.

Demystifying the Test File

Viewing the generated test file NVExampleTests , we can see a lot of pre-generated functions. It's always good to have one test for each class.

The file starts with a XCTest framework import. All test cases need to import the XCTest framework. We will cover later what all does the XCTest framework contains.

You can also see the main module import (@testable import NVExample)in the second line with a @testable keyword. Whatever code is written in the Application will come inside that import module

In the class declaration, we can see the class name same as the file name, here in our case the class name will NVExampleTests and it will be conforming to/ a subclass of XCTestCase

Understanding the methods in the class:
- setUpWithError method is invoked before a unit test is run
- tearDownWithError method is invoked after a unit test is run
- testExample method is a normal unit test
- testPerformanceExample method is used to test methods or functions that perform time-critical computations

Writing a Test Case

We will write a simple function to count the number of digits in a string in our ViewController class like the one below.

func numberOfNumericalCharacters(in input: String) -> Int {
let numericals = input.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)

return numericals.count
}

Here we use a regular expression [^0-9] to find any character that is NOT a digit and then replace those with an empty/blank character.

Now, will we write the test case for this?

For that, we will open the NVExampleTests and inside the class, we will add a function and name it test_numberOfNumericalCharacters

For the assertions, the XCTest framework itself provides multiple assert functions like the below:

  • Equality: XCTAssertEqual, XCTAssertNotEqual
  • Truthiness: XCTAssertTrue, XCTAssertFalse
  • Nullability: XCTAssertNil, XCTAssertNotNil
  • Comparison: XCTAssertLessThan, XCTAssertGreaterThan, XCTAssertLessThanOrEqual, XCTAssertGreaterThanOrEqual
  • Erroring: XCTAssertThrowsError, XCTAssertNoThrow

In our example, we will be using the XCTAssertEqual function. Within the test function which we just added we will write our test code.

First, we will create an instance of ViewController and assign it to a constant. We will name that constant as viewController

Using this constant we will call the function that we want to test(numberOfNumericalCharacters) and will assign this to another constant named result

Now we will check if the result’s value is equal to our expected value. For that, we will be using the XCTest frameworks function XCTAssertEqual.

Finally, our test code will look like the below:

func test_numberOfNumericalCharacters() {
let viewController = ViewController()

let result = viewController.numberOfNumericalCharacters(in: "Nikilicious09")

XCTAssertEqual(result, 3, "The result value \(result) is not same as the expected value ❌")
}

Here I have generated a failure case. So once you press CMD + U (the shortcut for testing in Xcode). Once the testing is done it will prompt you with failures like the below screenshots. You can see a red cross beside the test function which means the test has failed.

Now we will generate a pass case. We will simply replace the expected value from 3 to 2. And again run tests by pressing CMD + U . Now you can see a green tick beside the test function. This means that the test has been passed.

Extra Note: You might have now noticed that Xcode also runs the UI test in the NVExampleUITests target and this will be making your UnitTests get done slowly. For that, we just need to disable the UITests by doing the following.
- Go to the scheme selection, and click on the Edit Scheme option
- Now the scheme editor options window will be opened. Select the Test option from the side menu and uncheck the NVExampleUITests . Now this will disable the UITests and definitely will improve the speed of tests.

I hope you understood the much-needed and must-to-know basics of Unit Testing in Swift. This is just the start of Unit Testing there are a lot more. I will strongly recommend you to exercise with other assert functions also. Next up I will be covering how we can test asynchronous code.

Thanks for reading.

--

--