How to write Unit Tests for Code Performance ⏱️


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


Did you know that it’s possible to write unit tests for code performance?

Let’s take the example of this function:

As you can see, this function is a toy example for costly code that will take some time to execute.

And with this kind of code, it’s important to monitor that we don’t increase its execution time by mistake.

So let’s write a test to check that the execution time hasn’t changed!

We’re going to move to the unit test target and write a test that uses the function measure():

This function works a bit differently than your regular test assertions.

The first time we run the test, the function measure() will execute the code inside its closure 10 times and average the execution time.

We can then set this result as a baseline, which will be saved in the settings of the Xcode project.

And from that point, the next time that we run the test if the average execution time has increased by more than the allowed maximum deviation percentage, then the test will fail.

So let’s give it a try!

I’ll update my code to make my example function take twice as long to execute…

…now if I run the test again, it does detect that the execution time has increased by more than the allowed margin, and so the test fails.

By the way, the execution time is not the only metric that the function measure() can track: you could also monitor, among others, memory or storage consumption.

That’s all for this article, I hope you’ve enjoyed learning this testing feature!

Here’s the code if you want to experiment with it:

// App Code
import Foundation

func costlyFunction() -> Int {
    var result = 0
    for i in 1...2_000_000 {
        result += i
    }
    return result
}

// Test Code
import XCTest
@testable import TestPerformance

final class TestPerformanceTests: XCTestCase {
    func testPerformance() throws {
        measure(metrics: [XCTMemoryMetric(), XCTStorageMetric()]) {
            let _ = costlyFunction()
        }
    }
}
Previous
Previous

Hidden feature: subscript

Next
Next

How to easily debug your network code 🛰️