Converting XCTest `invokeTest` to Swift Testing

I'm converting tests from XCTest to Swift Testing and I'm not sure how to best deal with invokeTest. We're using it to apply a RAII type wrapper withDependency (from swift-dependenices) to all test functions:

    override func invokeTest() {
        withDependencies {
            $0.date.now = .t0
            ... longer list of dependency setup ...
        } operation: {
            super.invokeTest()
        }
    }

Of course, the brute force method of moving the withDependencies { ... } into the test functions would work but that's a lot of code duplication and just general churn.

Is there a way to achieve something similar with Swift Testing? A custom trait perhaps?

2 Likes

Hm, swift-dependencies has SuiteTraits and TestTraits. Would those work for your use case: swift-dependencies/Sources/DependenciesTestSupport/TestTrait.swift at main · pointfreeco/swift-dependencies · GitHub

Oooh, that's great. I think the SuiteTrait would do what I need, I'll need to check that out. Thanks a lot for the pointer!

See the recently-approved Test Scoping Traits feature in particular to accomplish this—it’s coming in Swift 6.1. If you use SuiteTrait, pay attention to the isRecursive property and how it relates to the feature (documented in that proposal). I’m happy to answer questions about it.

2 Likes

Yeah, we've done our best to support scoping dependencies for a test/suite using the existing traits infrastructure, but it's only a partial solution. In particular, our traits cannot support repeated runs of a test because the dependencies for each run are shared.

But once scoped traits are officially released we will be able to properly support a .dependency test trait.

4 Likes

Just to follow up on this, I tried both the suite and the test .dependency traits and it did not correctly resolve dependencies for me (Swift 6.0.3, macOS).

I'll work around this for now and try again when 6.1 has been released.

Thanks for the tips and pointers, everyone!

3 Likes