diff --git a/Sources/Testing/ABI/EntryPoints/EntryPoint.swift b/Sources/Testing/ABI/EntryPoints/EntryPoint.swift index 4d510ccba..7a2e63003 100644 --- a/Sources/Testing/ABI/EntryPoints/EntryPoint.swift +++ b/Sources/Testing/ABI/EntryPoints/EntryPoint.swift @@ -42,7 +42,7 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha // Set up the event handler. configuration.eventHandler = { [oldEventHandler = configuration.eventHandler] event, context in - if case let .issueRecorded(issue) = event.kind, !issue.isKnown, issue.severity >= .error { + if case let .issueRecorded(issue) = event.kind, issue.isFailure { exitCode.withLock { exitCode in exitCode = EXIT_FAILURE } diff --git a/Sources/Testing/Issues/Issue.swift b/Sources/Testing/Issues/Issue.swift index d210ecec7..53364c151 100644 --- a/Sources/Testing/Issues/Issue.swift +++ b/Sources/Testing/Issues/Issue.swift @@ -103,6 +103,21 @@ public struct Issue: Sendable { /// The severity of this issue. @_spi(Experimental) public var severity: Severity + + /// Whether or not this issue should cause the test it's associated with to be + /// considered a failure. + /// + /// The value of this property is `true` for issues which have a severity level of + /// ``Issue/Severity/error`` or greater and are not known issues via + /// ``withKnownIssue(_:isIntermittent:sourceLocation:_:when:matching:)``. + /// Otherwise, the value of this property is `false.` + /// + /// Use this property to determine if an issue should be considered a failure, instead of + /// directly comparing the value of the ``severity`` property. + @_spi(Experimental) + public var isFailure: Bool { + return !self.isKnown && self.severity >= .error + } /// Any comments provided by the developer and associated with this issue. /// diff --git a/Tests/TestingTests/IssueTests.swift b/Tests/TestingTests/IssueTests.swift index cb7ce28f3..6ea1a5827 100644 --- a/Tests/TestingTests/IssueTests.swift +++ b/Tests/TestingTests/IssueTests.swift @@ -1011,6 +1011,7 @@ final class IssueTests: XCTestCase { } XCTAssertFalse(issue.isKnown) XCTAssertEqual(issue.severity, .error) + XCTAssertTrue(issue.isFailure) guard case .unconditional = issue.kind else { XCTFail("Unexpected issue kind \(issue.kind)") return @@ -1031,6 +1032,7 @@ final class IssueTests: XCTestCase { } XCTAssertFalse(issue.isKnown) XCTAssertEqual(issue.severity, .warning) + XCTAssertFalse(issue.isFailure) guard case .unconditional = issue.kind else { XCTFail("Unexpected issue kind \(issue.kind)") return diff --git a/Tests/TestingTests/KnownIssueTests.swift b/Tests/TestingTests/KnownIssueTests.swift index 448b8e35d..733fbbf01 100644 --- a/Tests/TestingTests/KnownIssueTests.swift +++ b/Tests/TestingTests/KnownIssueTests.swift @@ -10,7 +10,7 @@ #if canImport(XCTest) import XCTest -@testable @_spi(ForToolsIntegrationOnly) import Testing +@testable @_spi(Experimental) @_spi(ForToolsIntegrationOnly) import Testing final class KnownIssueTests: XCTestCase { func testIssueIsKnownPropertyIsSetCorrectly() async { @@ -26,6 +26,7 @@ final class KnownIssueTests: XCTestCase { issueRecorded.fulfill() XCTAssertTrue(issue.isKnown) + XCTAssertFalse(issue.isFailure) } await Test {