Swift Testing - load data before the tests start

4 weeks ago 28
ARTICLE AD BOX

This can be done with Test Scoping, introduced in ST-0007.

You can create a SuiteTrait that also conforms to TestScoping, and do your setup in the provideScope method.

struct DataLibraryTrait: SuiteTrait, TestScoping { func provideScope(for test: Test, testCase: Test.Case?, performing function: @Sendable () async throws -> Void) async throws { print("Setting up once and for all...") try await dataLibrary.load() try await function() print("Tearing down...") } } extension SuiteTrait where Self == DataLibraryTrait { static var useDataLibrary: DataLibraryTrait { .init() } }

If you can apply this trait to a @Suite, the code before try await function() will be run once for all (not for each) of the tests/subsuites in that suite. Similarly, the code after try await function() will be run only once too.

As an example:

@Suite(.useDataLibrary) struct MyTestSuite { @Suite struct Subsuite1 { @Test func test1() async throws { print("Doing test 1") } @Test func test2() async throws { print("Doing test 2") } } @Suite struct Subsuite2 { @Test func test3() async throws { print("Doing test 3") } @Test func test4() async throws { print("Doing test 4") } } }

Running MyTestSuite produces the output:

􀟈 Suite MyTestSuite started. Setting up once and for all... 􀟈 Suite Subsuite2 started. 􀟈 Suite Subsuite1 started. 􀟈 Test test3() started. 􀟈 Test test4() started. 􀟈 Test test2() started. Doing test 3 Doing test 2 􁁛 Test test3() passed after 0.001 seconds. Doing test 4 􀟈 Test test1() started. 􁁛 Test test2() passed after 0.001 seconds. 􁁛 Test test4() passed after 0.001 seconds. Doing test 1 􁁛 Test test1() passed after 0.001 seconds. 􁁛 Suite Subsuite2 passed after 0.001 seconds. 􁁛 Suite Subsuite1 passed after 0.001 seconds. Tearing down... 􁁛 Suite MyTestSuite passed after 0.001 seconds. 􁁛 Test run with 4 tests in 3 suites passed after 0.001 seconds. Program ended with exit code: 0
Read Entire Article