Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add retry on failure support to JunitReporter #293

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
30 changes: 30 additions & 0 deletions Sources/XcbeautifyLib/JunitReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +28 to +29
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned about removing previous failed iterations. We can't guarantee that test iterations fail for the same reason, so consolidating them here would suppress potentially important information. Looking at the JUnit specification and conventions, I think the current logic is correct– iteration failures should be recorded individually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know much about JUnit but afaik there is no built-in support for the retry-on-failure mechanism so I don't think JUnit is opinionated.

It is acceptable to agree that if one of the retries succeeds, the output should not contain a failure from such a test.

However, I get your point if all the retry fails for different reasons, but should they be reported more than once if it is one test? Should we fail twice because the error is different even if there is just one test failing? or should we make some decisions and grab one?

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)
Comment on lines 34 to +37
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a developer enables the "Run tests repeatedly" option, and each iteration passes, this will only show as 1 success, right? I don't think that's the desired behavior, and I don't think the current proposed changes consider that scenario. It's not one covered by the existing unit tests, but it should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, pushed some changes, thanks!

components.append(.testCasePassed(testCase))
} else if TestCaseSkippedCaptureGroup.regex.match(string: line) {
guard let testCase = generateSkippedTest(line: line) else { return }
Expand Down Expand Up @@ -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] = []
Expand Down
195 changes: 195 additions & 0 deletions Tests/XcbeautifyLibTests/JunitReporterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,201 @@
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 = """
<testsuites name="All tests" tests="6" failures="0">
<testsuite name="XcbeautifyLibTests.OutputHandlerTests" tests="6" failures="0">
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testEarlyReturnIfEmptyString" time="0.054" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintOnlyTasksWithError" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintOnlyTasksWithWarningOrError" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintTestResultTooIfIsCIAndQuiet" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintTestResultTooIfIsCIAndQuieter" time="0.000" />
</testsuite>
</testsuites>
"""

private let expectedRetryOnFailureLinuxXml = """
<testsuites name="All tests" tests="6" failures="0">
<testsuite name="-[XcbeautifyLibTests" tests="6" failures="0">
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testEarlyReturnIfEmptyString]" time="0.054" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintOnlyTasksWithError]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintOnlyTasksWithWarningOrError]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]" time="0.000" />
</testsuite>
</testsuites>
"""

func testJunitReportWithSuccessRetry() throws {
let reporter = JunitReporter()
retryOnFailureTests.components(separatedBy: .newlines).forEach { reporter.add(line: $0) }

Check warning on line 469 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Convert functional forEach calls to for loops. (preferForLoop)

Check warning on line 469 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
let data = try reporter.generateReport()

Check warning on line 470 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
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 = """
<testsuites name="All tests" tests="6" failures="1">
<testsuite name="XcbeautifyLibTests.OutputHandlerTests" tests="6" failures="1">
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testEarlyReturnIfEmptyString">
<failure message="/Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13 - XCTAssertEqual failed: (&quot;Optional(&quot;Aggregate target Be Aggro of project AggregateExample with configuration Debug&quot;)&quot;) is not equal to (&quot;Optional(&quot;failing Aggregate target Be Aggro of project AggregateExample with configuration Debug&quot;)&quot;)" />
</testcase>
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintOnlyTasksWithError" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintOnlyTasksWithWarningOrError" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintTestResultTooIfIsCIAndQuiet" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintTestResultTooIfIsCIAndQuieter" time="0.000" />
</testsuite>
</testsuites>
"""

private let expectedFailingTestsRetryOnFailureLinuxXml = """
<testsuites name="All tests" tests="6" failures="1">
<testsuite name="-[XcbeautifyLibTests" tests="6" failures="1">
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testEarlyReturnIfEmptyString]">
<failure message="/Users/andres/Git/xcbeautify/Tests/XcbeautifyLibTests/OutputHandlerTests.swift:13 - XCTAssertEqual failed: (&quot;Optional(&quot;Aggregate target Be Aggro of project AggregateExample with configuration Debug&quot;)&quot;) is not equal to (&quot;Optional(&quot;failing Aggregate target Be Aggro of project AggregateExample with configuration Debug&quot;)&quot;)" />
</testcase>
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintOnlyTasksWithError]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintOnlyTasksWithWarningOrError]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintTestResultTooIfIsCIAndQuiet]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintTestResultTooIfIsCIAndQuieter]" time="0.000" />
</testsuite>
</testsuites>
"""

func testJunitReportWithFailingRetries() throws {
let reporter = JunitReporter()
failingRetryOnFailureTests.components(separatedBy: .newlines).forEach { reporter.add(line: $0) }

Check warning on line 540 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Convert functional forEach calls to for loops. (preferForLoop)

Check warning on line 540 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
let data = try reporter.generateReport()

Check warning on line 541 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
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 = """
<testsuites name="All tests" tests="6" failures="0">
<testsuite name="XcbeautifyLibTests.OutputHandlerTests" tests="6" failures="0">
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
<testcase classname="XcbeautifyLibTests.OutputHandlerTests" name="testPrintAllOutputTypeByDefault" time="0.000" />
</testsuite>
</testsuites>
"""

private let expectedTestsRunRepeatedlyLinuxXml = """
<testsuites name="All tests" tests="6" failures="0">
<testsuite name="-[XcbeautifyLibTests" tests="6" failures="0">
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
<testcase classname="-[XcbeautifyLibTests" name="OutputHandlerTests testPrintAllOutputTypeByDefault]" time="0.000" />
</testsuite>
</testsuites>
"""

func testJunitReportWithRepetitions() throws {
let reporter = JunitReporter()
runTestsRepeatedly.components(separatedBy: .newlines).forEach { reporter.add(line: $0) }

Check warning on line 599 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Convert functional forEach calls to for loops. (preferForLoop)

Check warning on line 599 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
let data = try reporter.generateReport()

Check warning on line 600 in Tests/XcbeautifyLibTests/JunitReporterTests.swift

View workflow job for this annotation

GitHub Actions / SwiftFormat

Wrap the bodies of inline loop statements onto a new line. (wrapLoopBodies)
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)'
Expand Down
Loading