Repository: swiftlang/swift-testing

Issue #36: API or mechanism to perform an action once before/after running all of the tests in a suite type
Created: 2023-09-28T22:04:17Z
Description
We should have an API or mechanism to perform an action once inside a suite type before or after running all of that suite's tests.
Conceptually, this would be similar to XCTest's class-level +setUp and +tearDown APIs, or what some other testing libraries call "BeforeAll" and "AfterAll". However, for a more modern Swift solution, it may be better to use a closure- or scoped access- style API, since that interoperates better with Swift concurrency and allows using @TaskLocal.
rdar://103616215
Expected behavior
No response
Actual behavior
No response
Steps to reproduce
No response
swift-testing version/commit hash
No response
Swift & OS version (output of swift --version && uname -a)
No response

Duplicate issue #225: class setUp/tearDown equivalents in swift-testing
Created: 2024-02-18T08:03:18Z
Description
For normal func setUp and func tearDown we can convert them to init and deinit call on our test class according to the doc here.
But what are the equivalents for class func setUp and class func tearDown here?
class TestCaseBase: XCTestCase {    
    override class func setUp() {
        // Class level init code
		print("[C] setup")
    }
    
    override class func tearDown() {
		// Class level deinit code
		print("[C] tearDown")
    }

    override func setUp() {
        // instance level init code
		...
		print("[I] setup")
    }
    
    override func tearDown() {
		// instance level deinit code
		...
		print("[I] tearDown")
    }
	
	func testMethod1() {}
	func testMethod2() {}
}
We'll get
[C] setup
[I] setup
[I] tearDown
[I] setup
[I] tearDown
[C] tearDown

After converting to swift-testing
@Suite
class TestCaseBase {
	// 🚧
   	class func setUp() {
        // Class level init code
		print("[C] setup")
    }
    
	// 🚧	
   	class func tearDown() {
		// Class level deinit code
		print("[C] tearDown")
    }

	init() {
        // instance level init code
		...
		print("[I] setup")
	}

    deinit {
		// instance level deinit code
		...
		print("[I] tearDown")
    }
	
	@Test 
	func method1() {}
	@Test
	func method2() {}
}
We'll get
[I] setup
[I] tearDown
[I] setup
[I] tearDown

Expected behavior
Get the equivalents behavior of XCTest
Actual behavior
Missing class level setUp and tearDown code.
Workaround
// Track it manually with `Bool` value to workaround class level setUp
```swift
@Suite
class AttributeTestBase {
    
    static var hasClassSetUp = false
    static var hasClassTearDown = false
    
    init() {
        if !Self.hasClassSetUp { // Ignore thread safety issues for now 🤔
            Self.setUp()
            Self.hasClassSetUp = true
        }
    }
    
    deinit {
        ...
    }
    
    class func setUp() { ... }
    
    class func tearDown() { ... }
}
final class ATest: TestBase {
	init() {
		super.init()
        // instance level init code
		...
		print("[I] setup")
	}

	deinit {
		// instance level deinit code
		...
		print("[I] tearDown")
	}

	@Test
	func method1() { ... }
	@Test
	func method2() { ... }
}
swift-testing version/commit hash
0.3.0

Closing comment (2024-02-18T12:52:20Z): Duplicate of #36