Skip to content

Commit bd66853

Browse files
authored
Do not emit a time= attribute in JUnit output for skipped tests. (#741)
Resolves #740. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent bf1479e commit bd66853

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

Sources/Testing/Events/Recorder/Event.JUnitXMLRecorder.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,15 @@ extension Event.JUnitXMLRecorder {
176176
let classNameComponents = CollectionOfOne(id.moduleName) + id.nameComponents.dropLast()
177177
let className = classNameComponents.joined(separator: ".")
178178
let name = id.nameComponents.last!
179-
let durationNanoseconds = testData.startInstant.nanoseconds(until: testData.endInstant ?? .now)
180-
let durationSeconds = Double(durationNanoseconds) / 1_000_000_000
179+
180+
// Tests that are skipped or for some reason never completed will not have
181+
// an end instant; don't report timing for such tests.
182+
var timeClause = ""
183+
if let endInstant = testData.endInstant {
184+
let durationNanoseconds = testData.startInstant.nanoseconds(until: endInstant)
185+
let durationSeconds = Double(durationNanoseconds) / 1_000_000_000
186+
timeClause = #"time="\#(durationSeconds)" "#
187+
}
181188

182189
// Build out any child nodes contained within this <testcase> node.
183190
var minutiae = [String]()
@@ -193,9 +200,9 @@ extension Event.JUnitXMLRecorder {
193200
}
194201

195202
if minutiae.isEmpty {
196-
result.append(#" <testcase classname="\#(className)" name="\#(name)" time="\#(durationSeconds)" />"#)
203+
result.append(#" <testcase classname="\#(className)" name="\#(name)" \#(timeClause)/>"#)
197204
} else {
198-
result.append(#" <testcase classname="\#(className)" name="\#(name)" time="\#(durationSeconds)">"#)
205+
result.append(#" <testcase classname="\#(className)" name="\#(name)" \#(timeClause)>"#)
199206
result += minutiae
200207
result.append(#" </testcase>"#)
201208
}

Tests/TestingTests/EventRecorderTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,28 @@ struct EventRecorderTests {
354354
throw caughtError
355355
}
356356
}
357+
358+
@Test(
359+
"JUnit XML omits time for skipped tests",
360+
.bug("https://github.com/swiftlang/swift-testing/issues/740")
361+
)
362+
func junitXMLWithTimelessSkippedTest() async throws {
363+
let stream = Stream()
364+
365+
let eventRecorder = Event.JUnitXMLRecorder(writingUsing: stream.write)
366+
eventRecorder.record(Event(.runStarted, testID: nil, testCaseID: nil), in: Event.Context(test: nil, testCase: nil, configuration: nil))
367+
let test = Test {}
368+
eventRecorder.record(Event(.testSkipped(.init(sourceContext: .init())), testID: test.id, testCaseID: nil), in: Event.Context(test: test, testCase: nil, configuration: nil))
369+
eventRecorder.record(Event(.runEnded, testID: nil, testCaseID: nil), in: Event.Context(test: nil, testCase: nil, configuration: nil))
370+
371+
let xmlString = stream.buffer.rawValue
372+
#expect(xmlString.hasPrefix("<?xml"))
373+
let testCaseLines = xmlString
374+
.split(whereSeparator: \.isNewline)
375+
.filter { $0.contains("<testcase") }
376+
#expect(!testCaseLines.isEmpty)
377+
#expect(!testCaseLines.contains { $0.contains("time=") })
378+
}
357379
#endif
358380

359381
@Test("HumanReadableOutputRecorder counts issues without associated tests")

0 commit comments

Comments
 (0)