Skip to content

Adjust duration output from the execution summary lines #23

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

Merged
merged 1 commit into from
Jan 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 30 additions & 32 deletions XCTest/XCTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,38 +31,37 @@ extension XCTestCase {
var totalDuration = 0.0
var totalFailures = 0
var unexpectedFailures = 0
for (name, test) in tests {
XCTCurrentTestCase = self
let method = "\(self.dynamicType).\(name)"
var duration: Double = 0.0
print("Test Case '\(method)' started.")

setUp()

let start = currentTimeIntervalSinceReferenceTime()
test()
let end = currentTimeIntervalSinceReferenceTime()

tearDown()

duration = end - start
totalDuration += duration
for failure in XCTCurrentFailures {
failure.emit(method)
totalFailures += 1
if !failure.expected {
unexpectedFailures += 1
let overallDuration = measureTimeExecutingBlock {
for (name, test) in tests {
XCTCurrentTestCase = self
let method = "\(self.dynamicType).\(name)"
print("Test Case '\(method)' started.")

setUp()

let duration = measureTimeExecutingBlock(test)

tearDown()

totalDuration += duration
for failure in XCTCurrentFailures {
failure.emit(method)
totalFailures += 1
if !failure.expected {
unexpectedFailures += 1
}
}
var result = "passed"
if XCTCurrentFailures.count > 0 {
result = "failed"
}
print("Test Case '\(method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
XCTAllRuns.append(XCTRun(duration: duration, method: method, passed: XCTCurrentFailures.count == 0, failures: XCTCurrentFailures))
XCTCurrentFailures.removeAll()
XCTCurrentTestCase = nil
}
var result = "passed"
if XCTCurrentFailures.count > 0 {
result = "failed"
}
print("Test Case '\(method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
XCTAllRuns.append(XCTRun(duration: duration, method: method, passed: XCTCurrentFailures.count == 0, failures: XCTCurrentFailures))
XCTCurrentFailures.removeAll()
XCTCurrentTestCase = nil
}

var testCountSuffix = "s"
if tests.count == 1 {
testCountSuffix = ""
Expand All @@ -71,9 +70,8 @@ extension XCTestCase {
if totalFailures == 1 {
failureSuffix = ""
}
let averageDuration = totalDuration / Double(tests.count)

print("Executed \(tests.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(unexpectedFailures) unexpected) in \(printableStringForTimeInterval(averageDuration)) (\(printableStringForTimeInterval(totalDuration))) seconds")

print("Executed \(tests.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(unexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
}

// 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)
Expand Down
13 changes: 8 additions & 5 deletions XCTest/XCTestMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct XCTFailure {
}

internal struct XCTRun {
var duration: Double
var duration: TimeInterval
var method: String
var passed: Bool
var failures: [XCTFailure]
Expand All @@ -44,9 +44,12 @@ internal struct XCTRun {
/// 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)`.
/// - Parameter testCases: An array of test cases to run.
@noreturn public func XCTMain(testCases: [XCTestCase]) {
for testCase in testCases {
testCase.invokeTest()
let overallDuration = measureTimeExecutingBlock {
for testCase in testCases {
testCase.invokeTest()
}
}

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) }

var testCountSuffix = "s"
Expand All @@ -57,8 +60,8 @@ internal struct XCTRun {
if totalFailures == 1 {
failureSuffix = ""
}
let averageDuration = totalDuration / Double(XCTAllRuns.count)
print("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(averageDuration)) (\(printableStringForTimeInterval(totalDuration))) seconds")

print("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
exit(totalFailures > 0 ? 1 : 0)
}

Expand Down
20 changes: 15 additions & 5 deletions XCTest/XCTimeUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,28 @@
import Darwin
#endif

internal typealias TimeInterval = Double

/// Returns the number of seconds since the reference time as a Double.
internal func currentTimeIntervalSinceReferenceTime() -> Double {
private func currentTimeIntervalSinceReferenceTime() -> TimeInterval {
var tv = timeval()
let currentTime = withUnsafeMutablePointer(&tv, { (t: UnsafeMutablePointer<timeval>) -> Double in
let currentTime = withUnsafeMutablePointer(&tv, { (t: UnsafeMutablePointer<timeval>) -> TimeInterval in
gettimeofday(t, nil)
return Double(t.memory.tv_sec) + Double(t.memory.tv_usec) / 1000000.0
return TimeInterval(t.memory.tv_sec) + TimeInterval(t.memory.tv_usec) / 1000000.0
})
return currentTime
}

/// Execute the given block and return the time spent during execution
internal func measureTimeExecutingBlock(@noescape block: () -> Void) -> TimeInterval {
let start = currentTimeIntervalSinceReferenceTime()
block()
let end = currentTimeIntervalSinceReferenceTime()

return end - start
}

/// Returns a string version of the given time interval rounded to no more than 3 decimal places.
internal func printableStringForTimeInterval(timeInterval: Double) -> String {
internal func printableStringForTimeInterval(timeInterval: TimeInterval) -> String {
return String(round(timeInterval * 1000.0) / 1000.0)
}