Performance testing in Swift using the XCTest framework

In Swift, we can do performance testing using the XCTest framework, which is a part of the Xcode development environment. XCTest provides a comprehensive set of tools for writing, running, and analyzing unit and performance tests for Swift applications. This week we will learn how to do performance testing in Swift using the XCTest framework.

Build with Xcode, Ship with Helm.
The all-in-one macOS app that enhances App Store Connect, supercharging your app updates, localization, and ASO with AI-powered tools. Save 25% and try now!

The XCTest framework includes support for measuring the performance of specific code paths in your application using XCTest’s performance testing API. This API allows you to write tests that measure the execution time of a particular block of code, and we can use it to measure how the performance of your application changes over time as you make changes to your code.

To measure the performance of a specific code path, you can use the measure function provided by the XCTest framework. This function takes a closure containing the code you want to measure, and it runs that code multiple times to accurately measure its performance.

import XCTest

final class PerformanceTests: XCTestCase {
    func testPerformanceOfMyFunction() {
        self.measure {
            myFunction()
        }
    }
}

When you run this test, the measure function will run the code inside the closure multiple times and calculate the average execution time. It will also report the minimum and maximum execution times

Remember that we should use the measure function to measure the performance of small code paths, such as a single method or function. Don’t use the measure function to measure the performance of an entire application or a large portion of code, as this can lead to inaccurate results.

To test the performance of larger code paths, we can use another overload of the measure function, allowing us to specify a particular metric or set of metrics to measure while testing.

import XCTest

final class PerformanceTests: XCTestCase {
    var app: XCUIApplication!

    override func setUp() {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launch()
    }
    
    func testPerformanceOfSearchFlow() {
         self.measure(metrics: [XCTMemoryMetric()]) {
            SearchScreen(app: app)
                .goToSearch()
                .query("Pasta")
                .verifyResults(contains: "Pasta")
        }
    }
}

As you can see in the example above, we create an instance of the XCTMemoryMetric type to measure only memory usage. There are a bunch of available metric types like XCTApplicationLaunchMetric, XCTMemoryMetric, XCTCPUMetric, XCTStorageMetric, XCTClockMetric, and XCTOSSignpostMetric.

To learn about the Page Object pattern I’ve used in the example above, take a look at my “UI Testing using Page Object pattern in Swift” post.

You can use these measurements to optimize the performance of your code by identifying any bottlenecks or areas where the execution time is longer than expected.

In this article, we’ve explored the XCTest framework and its capabilities for performance testing in Swift. We’ve learned how to write and run performance tests using the XCTest framework. I hope you enjoy the post. Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading, and see you next week!

Written by ChatGPT, redacted by Majid Jabrayilov.