Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait in a XCTest for T seconds without timeout error?

Tags:

I want to delay progression of a test for T seconds, without generating a timeout.

First I tried the obvious:

sleep(5)
XCTAssert(<test if state is correct after this delay>)

But that failed.

Then I tried:

let promise = expectation(description: "Just wait 5 seconds")
waitForExpectations(timeout: 5) { (error) in
    promise.fulfill()

    XCTAssert(<test if state is correct after this delay>)
}

My XCTAssert() now succeeded. But waitForExpectations() failed with a timeout.

This is according to the documentation of XCTest wait functions saying:

Timeout is always treated as a test failure.

What are my options?

like image 731
meaning-matters Avatar asked May 09 '18 07:05

meaning-matters


3 Answers

You can use XCTWaiter.wait functions; for example:

 let exp = expectation(description: "Test after 5 seconds")
 let result = XCTWaiter.wait(for: [exp], timeout: 5.0)
 if result == XCTWaiter.Result.timedOut {
     XCTAssert(<test if state is correct after this delay>)
 } else {
     XCTFail("Delay interrupted")
 }
like image 116
A.Munzer Avatar answered Sep 28 '22 05:09

A.Munzer


If you know how much time something will take and simply want to wait that duration before continuing the test, you can use this one line:

_ = XCTWaiter.wait(for: [expectation(description: "Wait for n seconds")], timeout: 2.0)
like image 36
Robin Stewart Avatar answered Sep 28 '22 05:09

Robin Stewart


What best worked for me was:

let timeInSeconds = 2.0 // time you need for other tasks to be finished
let expectation = XCTestExpectation(description: "Your expectation")

DispatchQueue.main.asyncAfter(deadline: .now() + timeInSeconds) {
    expectation.fulfill()
}    

wait(for: [expectation], timeout: timeInSeconds + 1.0) // make sure it's more than what you used in AsyncAfter call.

// do your XCTAssertions here
XCTAssertNotNil(value)
like image 28
André Henrique da Silva Avatar answered Sep 28 '22 05:09

André Henrique da Silva