Skip to content

Commit 4dd0e23

Browse files
author
Mike Ferris
committed
Merge pull request #23 from briancroom/improveDurationOutput
Adjust duration output from the execution summary lines
2 parents 4b5ea85 + 61ddd74 commit 4dd0e23

File tree

3 files changed

+53
-42
lines changed

3 files changed

+53
-42
lines changed

XCTest/XCTestCase.swift

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,38 +31,37 @@ extension XCTestCase {
3131
var totalDuration = 0.0
3232
var totalFailures = 0
3333
var unexpectedFailures = 0
34-
for (name, test) in tests {
35-
XCTCurrentTestCase = self
36-
let method = "\(self.dynamicType).\(name)"
37-
var duration: Double = 0.0
38-
print("Test Case '\(method)' started.")
39-
40-
setUp()
41-
42-
let start = currentTimeIntervalSinceReferenceTime()
43-
test()
44-
let end = currentTimeIntervalSinceReferenceTime()
45-
46-
tearDown()
47-
48-
duration = end - start
49-
totalDuration += duration
50-
for failure in XCTCurrentFailures {
51-
failure.emit(method)
52-
totalFailures += 1
53-
if !failure.expected {
54-
unexpectedFailures += 1
34+
let overallDuration = measureTimeExecutingBlock {
35+
for (name, test) in tests {
36+
XCTCurrentTestCase = self
37+
let method = "\(self.dynamicType).\(name)"
38+
print("Test Case '\(method)' started.")
39+
40+
setUp()
41+
42+
let duration = measureTimeExecutingBlock(test)
43+
44+
tearDown()
45+
46+
totalDuration += duration
47+
for failure in XCTCurrentFailures {
48+
failure.emit(method)
49+
totalFailures += 1
50+
if !failure.expected {
51+
unexpectedFailures += 1
52+
}
5553
}
54+
var result = "passed"
55+
if XCTCurrentFailures.count > 0 {
56+
result = "failed"
57+
}
58+
print("Test Case '\(method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
59+
XCTAllRuns.append(XCTRun(duration: duration, method: method, passed: XCTCurrentFailures.count == 0, failures: XCTCurrentFailures))
60+
XCTCurrentFailures.removeAll()
61+
XCTCurrentTestCase = nil
5662
}
57-
var result = "passed"
58-
if XCTCurrentFailures.count > 0 {
59-
result = "failed"
60-
}
61-
print("Test Case '\(method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
62-
XCTAllRuns.append(XCTRun(duration: duration, method: method, passed: XCTCurrentFailures.count == 0, failures: XCTCurrentFailures))
63-
XCTCurrentFailures.removeAll()
64-
XCTCurrentTestCase = nil
6563
}
64+
6665
var testCountSuffix = "s"
6766
if tests.count == 1 {
6867
testCountSuffix = ""
@@ -71,9 +70,8 @@ extension XCTestCase {
7170
if totalFailures == 1 {
7271
failureSuffix = ""
7372
}
74-
let averageDuration = totalDuration / Double(tests.count)
75-
76-
print("Executed \(tests.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(unexpectedFailures) unexpected) in \(printableStringForTimeInterval(averageDuration)) (\(printableStringForTimeInterval(totalDuration))) seconds")
73+
74+
print("Executed \(tests.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(unexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
7775
}
7876

7977
// This function is for the use of XCTestCase only, but we must make it public or clients will get a link failure when using XCTest (23476006)

XCTest/XCTestMain.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct XCTFailure {
3030
}
3131

3232
internal struct XCTRun {
33-
var duration: Double
33+
var duration: TimeInterval
3434
var method: String
3535
var passed: Bool
3636
var failures: [XCTFailure]
@@ -44,9 +44,12 @@ internal struct XCTRun {
4444
/// This function will not return. If the test cases pass, then it will call `exit(0)`. If there is a failure, then it will call `exit(1)`.
4545
/// - Parameter testCases: An array of test cases to run.
4646
@noreturn public func XCTMain(testCases: [XCTestCase]) {
47-
for testCase in testCases {
48-
testCase.invokeTest()
47+
let overallDuration = measureTimeExecutingBlock {
48+
for testCase in testCases {
49+
testCase.invokeTest()
50+
}
4951
}
52+
5053
let (totalDuration, totalFailures, totalUnexpectedFailures) = XCTAllRuns.reduce((0.0, 0, 0)) { totals, run in (totals.0 + run.duration, totals.1 + run.failures.count, totals.2 + run.unexpectedFailures.count) }
5154

5255
var testCountSuffix = "s"
@@ -57,8 +60,8 @@ internal struct XCTRun {
5760
if totalFailures == 1 {
5861
failureSuffix = ""
5962
}
60-
let averageDuration = totalDuration / Double(XCTAllRuns.count)
61-
print("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(averageDuration)) (\(printableStringForTimeInterval(totalDuration))) seconds")
63+
64+
print("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
6265
exit(totalFailures > 0 ? 1 : 0)
6366
}
6467

XCTest/XCTimeUtilities.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,28 @@
1717
import Darwin
1818
#endif
1919

20+
internal typealias TimeInterval = Double
21+
2022
/// Returns the number of seconds since the reference time as a Double.
21-
internal func currentTimeIntervalSinceReferenceTime() -> Double {
23+
private func currentTimeIntervalSinceReferenceTime() -> TimeInterval {
2224
var tv = timeval()
23-
let currentTime = withUnsafeMutablePointer(&tv, { (t: UnsafeMutablePointer<timeval>) -> Double in
25+
let currentTime = withUnsafeMutablePointer(&tv, { (t: UnsafeMutablePointer<timeval>) -> TimeInterval in
2426
gettimeofday(t, nil)
25-
return Double(t.memory.tv_sec) + Double(t.memory.tv_usec) / 1000000.0
27+
return TimeInterval(t.memory.tv_sec) + TimeInterval(t.memory.tv_usec) / 1000000.0
2628
})
2729
return currentTime
2830
}
2931

32+
/// Execute the given block and return the time spent during execution
33+
internal func measureTimeExecutingBlock(@noescape block: () -> Void) -> TimeInterval {
34+
let start = currentTimeIntervalSinceReferenceTime()
35+
block()
36+
let end = currentTimeIntervalSinceReferenceTime()
37+
38+
return end - start
39+
}
40+
3041
/// Returns a string version of the given time interval rounded to no more than 3 decimal places.
31-
internal func printableStringForTimeInterval(timeInterval: Double) -> String {
42+
internal func printableStringForTimeInterval(timeInterval: TimeInterval) -> String {
3243
return String(round(timeInterval * 1000.0) / 1000.0)
3344
}
34-

0 commit comments

Comments
 (0)