Skip to content

Commit f073f8b

Browse files
authored
Merge pull request #63 from gfontenot/gfontenot/report-all-failures-to-junit
Add all failures for a given test to the JUnit report
2 parents 0a0cfb7 + 65de2a5 commit f073f8b

File tree

2 files changed

+107
-6
lines changed

2 files changed

+107
-6
lines changed

Sources/xcresultparser/JunitXML.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,13 @@ public struct JunitXML: XmlSerializable {
293293
nodeNames: nodeNames
294294
)
295295
if test.isFailed {
296-
if let summary = test.failureSummary(in: failureSummaries) {
297-
testcase.addChild(summary.failureXML(projectRoot: projectRoot))
298-
} else {
296+
let summaries = test.failureSummaries(in: failureSummaries)
297+
if summaries.isEmpty {
299298
testcase.addChild(failureWithoutSummary)
299+
} else {
300+
for summary in summaries {
301+
testcase.addChild(summary.failureXML(projectRoot: projectRoot))
302+
}
300303
}
301304
} else if test.isSkipped {
302305
testcase.addChild(skippedWithoutSummary)
@@ -321,7 +324,7 @@ extension XMLElement {
321324
}
322325
}
323326

324-
private extension ActionTestMetadata {
327+
extension ActionTestMetadata {
325328
func xmlNode(
326329
classname: String,
327330
numFormatter: NumberFormatter,
@@ -348,8 +351,8 @@ private extension ActionTestMetadata {
348351
return testcase
349352
}
350353

351-
func failureSummary(in summaries: [TestFailureIssueSummary]) -> TestFailureIssueSummary? {
352-
return summaries.first { summary in
354+
func failureSummaries(in summaries: [TestFailureIssueSummary]) -> [TestFailureIssueSummary] {
355+
return summaries.filter { summary in
353356
return summary.testCaseName == identifier?.replacingOccurrences(of: "/", with: ".") ||
354357
summary.testCaseName == "-[\(identifier?.replacingOccurrences(of: "/", with: " ") ?? "")]"
355358
}

Tests/XcresultparserTests/XcresultparserTests.swift

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
@testable import XcresultparserLib
3+
import XCResultKit
34
import Testing
45

56
@MainActor
@@ -499,6 +500,73 @@ struct XcresultparserTests {
499500
try assertXmlTestReportsAreEqual(expectedFileName: "junit_repeated", actual: junitXML)
500501
}
501502

503+
@Test
504+
func testFailureSummariesReturnsAllMatchingFailures() throws {
505+
let testMetadata = try makeTestMetadata()
506+
507+
let matchingFailure1 = try makeFailureSummary(
508+
testCaseName: "TestClass.testMethod",
509+
message: "First assertion failed"
510+
)
511+
let matchingFailure2 = try makeFailureSummary(
512+
testCaseName: "TestClass.testMethod",
513+
message: "Second assertion failed"
514+
)
515+
let nonMatchingFailure = try makeFailureSummary(
516+
testCaseName: "OtherClass.otherMethod",
517+
message: "Unrelated failure"
518+
)
519+
520+
let result = testMetadata.failureSummaries(in: [matchingFailure1, nonMatchingFailure, matchingFailure2])
521+
522+
#expect(result.count == 2)
523+
#expect(result[0].message == "First assertion failed")
524+
#expect(result[1].message == "Second assertion failed")
525+
}
526+
527+
@Test
528+
func testFailureSummariesWithBracketNotation() throws {
529+
let testMetadata = try makeTestMetadata()
530+
531+
// Objective-C bracket notation: -[TestClass testMethod]
532+
let bracketFailure1 = try makeFailureSummary(
533+
testCaseName: "-[TestClass testMethod]",
534+
message: "Bracket notation failure 1"
535+
)
536+
let bracketFailure2 = try makeFailureSummary(
537+
testCaseName: "-[TestClass testMethod]",
538+
message: "Bracket notation failure 2"
539+
)
540+
541+
let result = testMetadata.failureSummaries(in: [bracketFailure1, bracketFailure2])
542+
543+
#expect(result.count == 2)
544+
#expect(result[0].message == "Bracket notation failure 1")
545+
#expect(result[1].message == "Bracket notation failure 2")
546+
}
547+
548+
@Test
549+
func testFailureSummariesReturnsEmptyForNoMatches() throws {
550+
let testMetadata = try makeTestMetadata()
551+
let nonMatchingFailure = try makeFailureSummary(
552+
testCaseName: "OtherClass.otherMethod",
553+
message: "Unrelated failure"
554+
)
555+
556+
let result = testMetadata.failureSummaries(in: [nonMatchingFailure])
557+
558+
#expect(result.isEmpty)
559+
}
560+
561+
@Test
562+
func testFailureSummariesWithEmptyArray() throws {
563+
let testMetadata = try makeTestMetadata()
564+
565+
let result = testMetadata.failureSummaries(in: [])
566+
567+
#expect(result.isEmpty)
568+
}
569+
502570
@Test
503571
func testCleanCodeWarnings() throws {
504572
let xcresultFile = Bundle.module.url(forResource: "test", withExtension: "xcresult")!
@@ -650,6 +718,36 @@ struct XcresultparserTests {
650718

651719
// MARK: helper functions
652720

721+
private func makeTestMetadata(
722+
identifier: String = "TestClass/testMethod",
723+
name: String = "testMethod",
724+
status: String = "Failure",
725+
duration: String = "0.5"
726+
) throws -> ActionTestMetadata {
727+
let json: [String: AnyObject] = [
728+
"_type": ["_name": "ActionTestMetadata"] as AnyObject,
729+
"identifier": ["_type": ["_name": "String"], "_value": identifier] as AnyObject,
730+
"name": ["_type": ["_name": "String"], "_value": name] as AnyObject,
731+
"testStatus": ["_type": ["_name": "String"], "_value": status] as AnyObject,
732+
"duration": ["_type": ["_name": "Double"], "_value": duration] as AnyObject
733+
]
734+
return try #require(ActionTestMetadata(json))
735+
}
736+
737+
private func makeFailureSummary(
738+
testCaseName: String,
739+
message: String = "Assertion failed",
740+
issueType: String = "Assertion Failure"
741+
) throws -> TestFailureIssueSummary {
742+
let json: [String: AnyObject] = [
743+
"_type": ["_name": "TestFailureIssueSummary"] as AnyObject,
744+
"testCaseName": ["_type": ["_name": "String"], "_value": testCaseName] as AnyObject,
745+
"issueType": ["_type": ["_name": "String"], "_value": issueType] as AnyObject,
746+
"message": ["_type": ["_name": "String"], "_value": message] as AnyObject
747+
]
748+
return try #require(TestFailureIssueSummary(json))
749+
}
750+
653751
func assertXmlTestReportsAreEqual(
654752
expectedFileName: String,
655753
actual: XmlSerializable,

0 commit comments

Comments
 (0)