To add delays in my tests I implemented this:
func execute(after: TimeInterval, testBlock: () -> Void) {
let result = XCTWaiter.wait(for: [expectation(description: "Delayed Test")], timeout: after)
if result == XCTWaiter.Result.timedOut {
testBlock()
} else {
XCTFail("Delay interrupted.")
}
}
Then I wrote a test:
func testExecute() {
var i = 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.40) {
i = 2
}
execute(after: 0.20) {
XCTAssert(i == 1)
}
execute(after: 0.15) {
XCTAssert(i == 1) // Fails once every three or four runs.
}
execute(after: 0.06) { // Never fails.
XCTAssert(i == 2)
}
}
Why does this second XCTAssert()
fail regularly?
This is the only thing running on my simulator. You'd expect some jitter, but shouldn't that stay with 1 or 2 times the system clock period of 1/60s?
It turns out that delays may take up to considerably longer (up to 200ms in this 2011 experiment: http://atastypixel.com/blog/experiments-with-precise-timing-in-ios/).
Must take sufficient margins when using this execute(after:testBlock:)
function.