diff --git a/Sources/Testing/Issues/KnownIssue.swift b/Sources/Testing/Issues/KnownIssue.swift index f59185388..17214c12c 100644 --- a/Sources/Testing/Issues/KnownIssue.swift +++ b/Sources/Testing/Issues/KnownIssue.swift @@ -77,6 +77,13 @@ struct KnownIssueScope: Sendable { /// - sourceLocation: The source location to which the issue should be /// attributed. private func _matchError(_ error: any Error, in scope: KnownIssueScope, comment: Comment?, sourceLocation: SourceLocation) throws { + // ExpectationFailedError is thrown by expectation checking functions to + // indicate a condition evaluated to `false`. Those functions record their + // own issue, so we don't need to create a new issue and attempt to match it. + if error is ExpectationFailedError { + return + } + let sourceContext = SourceContext(backtrace: Backtrace(forFirstThrowOf: error), sourceLocation: sourceLocation) var issue = Issue(kind: .errorCaught(error), comments: [], sourceContext: sourceContext) if let context = scope.matcher(issue) { diff --git a/Tests/TestingTests/KnownIssueTests.swift b/Tests/TestingTests/KnownIssueTests.swift index 9174bfdd8..88deef5ec 100644 --- a/Tests/TestingTests/KnownIssueTests.swift +++ b/Tests/TestingTests/KnownIssueTests.swift @@ -574,6 +574,26 @@ final class KnownIssueTests: XCTestCase { await fulfillment(of: [issueRecorded, knownIssueNotRecorded], timeout: 0.0) } + func testKnownIssueWithRequiredExpectationFailure() async { + let issueRecorded = expectation(description: "Issue recorded") + + var configuration = Configuration() + configuration.eventHandler = { event, _ in + guard case .issueRecorded = event.kind else { + return + } + issueRecorded.fulfill() + } + + await Test { + withKnownIssue { + try #require(Bool(false)) + } + }.run(configuration: configuration) + + await fulfillment(of: [issueRecorded], timeout: 0.0) + } + func testAsyncKnownIssueThatDoesNotAlwaysOccur() async { struct MyError: Error {}