diff --git a/Sources/XcbeautifyLib/JunitReporter.swift b/Sources/XcbeautifyLib/JunitReporter.swift index fe1facb0..7ef267e9 100644 --- a/Sources/XcbeautifyLib/JunitReporter.swift +++ b/Sources/XcbeautifyLib/JunitReporter.swift @@ -25,12 +25,16 @@ package final class JunitReporter { if FailingTestCaptureGroup.regex.match(string: line) { guard let testCase = generateFailingTest(line: line) else { return } + // reduce failing retrys, if any + components.removePreviousFailingTestsAfter(testCase) components.append(.failingTest(testCase)) } else if RestartingTestCaptureGroup.regex.match(string: line) { guard let testCase = generateRestartingTest(line: line) else { return } components.append(.failingTest(testCase)) } else if TestCasePassedCaptureGroup.regex.match(string: line) { guard let testCase = generatePassingTest(line: line) else { return } + // filter out failing retrys, if any + components.removePreviousFailingTestsAfter(testCase) components.append(.testCasePassed(testCase)) } else if TestCaseSkippedCaptureGroup.regex.match(string: line) { guard let testCase = generateSkippedTest(line: line) else { return } @@ -166,6 +170,32 @@ private enum JunitComponent { case skippedTest(TestCase) } +private extension JunitComponent { + var testCase: TestCase? { + switch self { + case .testSuiteStart: nil + case let .failingTest(testCase), let .testCasePassed(testCase), let .skippedTest(testCase): + testCase + } + } +} + +private extension [JunitComponent] { + mutating func removePreviousFailingTestsAfter(_ testCase: TestCase) { + // base case, empty array or last is not the given TestCase + guard let previousTestCase = last?.testCase, + previousTestCase.failure != nil, + testCase.classname == previousTestCase.classname, + testCase.name == previousTestCase.name + else { + return + } + removeLast() + // keep removing + removePreviousFailingTestsAfter(testCase) + } +} + private struct Testsuites: Encodable, DynamicNodeEncoding { var name: String? var testsuites: [Testsuite] = [] diff --git a/Tests/XcbeautifyLibTests/JunitReporterTests.swift b/Tests/XcbeautifyLibTests/JunitReporterTests.swift index 8885e59c..f5beae8e 100644 --- a/Tests/XcbeautifyLibTests/JunitReporterTests.swift +++ b/Tests/XcbeautifyLibTests/JunitReporterTests.swift @@ -412,6 +412,201 @@ class JunitReporterTests: XCTestCase { XCTAssertEqual(xml, expectedXml) } + private let retryOnFailureTests = """ + Test Suite 'All tests' started at 2021-11-05 01:08:23.237 + Test Suite 'xcbeautifyPackageTests.xctest' started at 2021-11-05 01:08:23.238 + Test Suite 'OutputHandlerTests' started at 2021-11-05 01:08:23.238 + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 1 of 3). + /Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13: error: -[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString] : XCTAssertEqual failed: ("Optional("Aggregate target Be Aggro of project AggregateExample with configuration Debug")") is not equal to ("Optional("failing Aggregate target Be Aggro of project AggregateExample with configuration Debug")") + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' failed (0.208 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 2 of 3). + /Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13: error: -[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString] : XCTAssertEqual failed: ("Optional("Aggregate target Be Aggro of project AggregateExample with configuration Debug")") is not equal to ("Optional("failing Aggregate target Be Aggro of project AggregateExample with configuration Debug")") + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' failed (0.208 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 3 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' passed (0.054 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithError]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithError]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithWarningOrError]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithWarningOrError]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]' passed (0.000 seconds). + Test Suite 'OutputHandlerTests' passed at 2021-11-05 01:08:23.294. + Executed 6 tests, with 0 failures (0 unexpected) in 0.055 (0.056) seconds + """ + + private let expectedRetryOnFailureXml = """ + + + + + + + + + + + """ + + private let expectedRetryOnFailureLinuxXml = """ + + + + + + + + + + + """ + + func testJunitReportWithSuccessRetry() throws { + let reporter = JunitReporter() + retryOnFailureTests.components(separatedBy: .newlines).forEach { reporter.add(line: $0) } + let data = try reporter.generateReport() + let xml = String(data: data, encoding: .utf8)! + #if os(Linux) + let expectedXml = expectedRetryOnFailureLinuxXml + #else + let expectedXml = expectedRetryOnFailureXml + #endif + XCTAssertEqual(xml, expectedXml) + } + + private let failingRetryOnFailureTests = """ + Test Suite 'All tests' started at 2021-11-05 01:08:23.237 + Test Suite 'xcbeautifyPackageTests.xctest' started at 2021-11-05 01:08:23.238 + Test Suite 'OutputHandlerTests' started at 2021-11-05 01:08:23.238 + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 1 of 3). + /Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13: error: -[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString] : XCTAssertEqual failed: ("Optional("Aggregate target Be Aggro of project AggregateExample with configuration Debug")") is not equal to ("Optional("failing Aggregate target Be Aggro of project AggregateExample with configuration Debug")") + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' failed (0.208 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 2 of 3). + /Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13: error: -[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString] : XCTAssertEqual failed: ("Optional("Aggregate target Be Aggro of project AggregateExample with configuration Debug")") is not equal to ("Optional("failing Aggregate target Be Aggro of project AggregateExample with configuration Debug")") + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' failed (0.208 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 3 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' started (Iteration 2 of 3). + /Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13: error: -[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString] : XCTAssertEqual failed: ("Optional("Aggregate target Be Aggro of project AggregateExample with configuration Debug")") is not equal to ("Optional("failing Aggregate target Be Aggro of project AggregateExample with configuration Debug")") + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testEarlyReturnIfEmptyString]' failed (0.208 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithError]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithError]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithWarningOrError]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintOnlyTasksWithWarningOrError]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]' started (Iteration 1 of 3). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]' passed (0.000 seconds). + Test Suite 'OutputHandlerTests' passed at 2021-11-05 01:08:23.294. + Executed 6 tests, with 0 failures (0 unexpected) in 0.055 (0.056) seconds + """ + + private let expectedFailingTestsRetryOnFailureXml = """ + + + + + + + + + + + + + """ + + private let expectedFailingTestsRetryOnFailureLinuxXml = """ + + + + + + + + + + + + + """ + + func testJunitReportWithFailingRetries() throws { + let reporter = JunitReporter() + failingRetryOnFailureTests.components(separatedBy: .newlines).forEach { reporter.add(line: $0) } + let data = try reporter.generateReport() + let xml = String(data: data, encoding: .utf8)! + #if os(Linux) + let expectedXml = expectedFailingTestsRetryOnFailureLinuxXml + #else + let expectedXml = expectedFailingTestsRetryOnFailureXml + #endif + XCTAssertEqual(xml, expectedXml) + } + + private let runTestsRepeatedly = """ + Test Suite 'All tests' started at 2021-11-05 01:08:23.237 + Test Suite 'xcbeautifyPackageTests.xctest' started at 2021-11-05 01:08:23.238 + Test Suite 'OutputHandlerTests' started at 2021-11-05 01:08:23.238 + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' started. + Test Case '-[XcbeautifyLibTests.OutputHandlerTests testPrintAllOutputTypeByDefault]' passed (0.000 seconds). + Test Suite 'OutputHandlerTests' passed at 2021-11-05 01:08:23.294. + Executed 6 tests, with 0 failures (0 unexpected) in 0.055 (0.056) seconds + """ + + private let expectedTestsRunRepeatedlyXml = """ + + + + + + + + + + + """ + + private let expectedTestsRunRepeatedlyLinuxXml = """ + + + + + + + + + + + """ + + func testJunitReportWithRepetitions() throws { + let reporter = JunitReporter() + runTestsRepeatedly.components(separatedBy: .newlines).forEach { reporter.add(line: $0) } + let data = try reporter.generateReport() + let xml = String(data: data, encoding: .utf8)! + #if os(Linux) + let expectedXml = expectedTestsRunRepeatedlyLinuxXml + #else + let expectedXml = expectedTestsRunRepeatedlyXml + #endif + XCTAssertEqual(xml, expectedXml) + } + private let parallelTests = """ Test suite 'MobileWebURLRouteTest' started on 'Clone 1 of iPhone 13 mini - xctest (32505)' Test suite 'BuildFlagTests' started on 'Clone 1 of iPhone 13 mini - xctest (32507)'