Description
Disclaimer
This issue is mainly for tracking for now. I think it can only be implemented if additional things are added to Swift Testing itself.
Context
Currently it is impossible to run Swift Testing tests repeatedly because the counter for the xxx.1.yyy
, xxx.2.yyy
naming does not get reset between test iterations. I tried a few things within SnapshotTesting testing to fix this, but nothing I can come up with is reliable.
What I tried
- Look for something similar to
XCTestObserver
to reset the counter when a test starts/ends. No such thing seems to exist. - Check
Test.current
and see if, for a given test function, it is different than the previous time that test function ran. This does not work becauseTest.current
is identical for each iteration. - Even though
Test
is a struct, we can still take anUnsafePointer
toTest.current
. We could check if it is different than the previous time that test function ran. As expected the struct frequently has the exact same address as the previous iteration so this is not a usable indicator. (It would anyway be unreliable at best.) - Check the current
#line
of theassertSnapshot
call. When there are multiple calls in 1 test then the line will always increase. If the line did not increase since the previous call for a given test function they we can assume the test ran again and reset the counter. This does not work when the test is callingassertSnapshot
inside a loop or for parametrized tests, so it is not usable as indication either. - Check "Relaunch Tests for Each Epetition" when running the test in Xcode. It has no effect.
I am out of ideas, but feel free to suggest something else I can try. I feel like the only reliable solution is that the Test
struct contains an iteration count that keeps track of this.
I created a request for Swift Testing to add such property. It can be tracked here: swiftlang/swift-testing#1041.
Caveat for implementation
Just something to keep in mind when implementing this.
For XCTest the counterMap is cleared when a test ends.
For Swift Testing we cannot do this because tests run in parallel. We can only remove/reset the count for the current test, otherwise we might accidentally reset the counter for other tests that are still running.