There are a few ways you may be able to achieve this:
For an individual test case, you could override the record(_ issue: XCTIssue)
which will be called for any assertion failures and should include its contextual information.
For example:
class MyCustomTests: XCTestCase {
// MARK: - Tests
func testExample() throws {
XCTAssertTrue(false, "some failing assertion")
XCTAssertEqual("A", "B", "another failing assertion")
}
// MARK: - Overrides
override func record(_ issue: XCTIssue) {
// process issues ...
super.record(issue)
}
}
References:
- https://developer.apple.com/documentation/xctest/xctestcase/3546549-record
- https://developer.apple.com/videos/play/wwdc2020/10687/
A more flexible approach that could scale to multiple test cases would be to leverage XCTestObservation
to observe all tests including occurrences of issues.
For example:
class MyTestObserver: NSObject, XCTestObservation {
func testCase(_ testCase: XCTestCase, didRecord issue: XCTIssue) {
// process issue ...
}
}
To get this wired up in a test bundle you could define a principle class (via setting NSPrincipleClass
in the Info plist) which would orchestrate the observation.
<key>NSPrincipalClass</key>
<string>MyCustomTestsManager</string>
@objc(MyCustomTestsManager)
class MyCustomTestsManager: NSObject {
private let observer = MyTestObserver()
override init() {
super.init()
XCTestObservationCenter.shared.addTestObserver(observer)
}
}
References:
- https://developer.apple.com/documentation/xctest/xctestobservation
- https://developer.apple.com/documentation/xctest/xctestobservationcenter