Leveraging XCTest’s Name in Unit Testing

Using the name of the test method to alter common code in setup for each individual test case

Dogan Altinbas
Plus Minus One
4 min readFeb 17, 2022

--

In PlusMinusOne, we develop, maintain, and deploy many iOS applications. As we have more apps we require a reliable delivery process for each project. One way to achieve this is to write unit tests. Once we add a new feature to our projects, we also write unit tests to make sure that even the smallest piece of code in the new feature works properly and does not introduce any failures. Eventually, it helps us to ensure that all code meets quality standards before it’s deployed.

Feature

In one of our apps, there is an instruction screen that lists gif tutorials about the app features. Users can navigate to this page from various screens. For this reason, once the instruction screen opens up, it should appear with the relevant gif tutorial scrolled at the top. For example, if the user opens the instruction screen from the main page it appears as follows:

Default Appearance of Instruction Screen

However, if the user taps the question mark button on the video recording page, the instruction screen opens up and scrolls the second gif tutorial to the top.

Video Recording Page ➡ Instruction Page

To handle this, InstructionType enum is defined and relative type is passed to the instruction screen to perform scroll operation as follows:

router.navigateToInstruction(with: .creatingAndSharingVideos)

Instruction Type Enum

Unit Test Architecture

We build iOS applications with VIPER architecture. P states the presenter in VIPER and it prepares business logic for presentation in the View. Also, it mediates between View and Interactor and uses a Router to move to different screens. It essentially orchestrates communication between all of those components. That is why we concentrate on testing the Presenter in unit tests. If you are starting completely from scratch, Musa Kökçen recently mentioned how to write unit tests in VIPER architecture:

Unit Test Scenarios

As you can see in the following, there are 5 test cases. These tests validate whether the instruction screen scrolls to relative enum value or not. This is checked by looking at the selected row value.

Test Cases

The enum value sent to the instruction screen has a different value for each test scenario. To achieve this, setUp() method is used, which is common to all test methods.

setUp() method provides an opportunity to reset the state before calling each test method in a test case.

Initial version setUp() method

Setup method mocks the router, interactor, view, and initializes the presenter before calling each test method. However, if it stays like above selectedInstructionType will be the same for each test case but that does not meet our criteria. So, the presenter variable can be initialized again to change selectedInstructionType in each test case. That would work but there is also a practical way not to initialize the presenter once again for each test case. To do this, first, the following enum is defined:

Test Cases Enum

TestCases enum cases represent test names and also instructionType variable returns relevant enum value for the name of the running test case. So how do we get the test name? For this, we need to do a few string operations in the setUp() method.

Modified version of setUp() Method

In the first line, XCTest has name variable that returns the currently running class name and test name. So, the test name is extracted from the name variable with just a few lines of code, and the enum value is initialized by using the test name as a raw value. In this way, the instruction type is set dynamically in the presenter on the last line. Now each test case has its own instructionType .

To learn more about our development experiences you can look at our medium page. At Plus Minus One, we love to learn and share our experiences. We hope this article makes your life easier 🙏🏻

--

--