Ponyboy47
(Jacob Williams)
1
What is the proper way to use XCTestExpectation on Linux? I'm working on a project that supports both macOS and Linux and I have an asynchronous test that compiles and runs on Mac, but fails to compile on Linux.
class BindingTests: XCTestCase {
func testAccepting() {
let socket = SocketPath("/tmp/com.trailblazer.sock")!
let binding: Binding
do {
binding = try socket.bind()
} catch {
XCTFail("Failed to bind to socket with error \(error)")
return
}
XCTAssertNoThrow(try binding.listen(maxQueued: 1))
let acceptConnection = XCTestExpectation(description: "Ensure connection is properly accepted")
DispatchQueue.global(qos: .background).async {
do {
try binding.accept() { _ in
acceptConnection.fulfill()
}
} catch {}
}
XCTAssertNoThrow(try socket.connect(type: TCPSocket.self))
XCTAssertEqual(XCTWaiter.wait(for: [acceptConnection], timeout: 5.0), .completed)
}
}
I get the following compilation errors on Linux:
error: cannot invoke initializer for type 'XCTestExpectation' with an argument list of type '(description: String)'
expected an argument list of type '(description: String, file: StaticString, line: Int, testCase: XCTestCase)'
and
error: use of unresolved identifier 'XCTWaiter'
If I change XCTestExpectation to initialize like this:
let acceptConnection = XCTestExpectation(description: "Ensure connection is properly accepted", file: #file, line: #line, testCase: self)
It fails to compile with this error instead:
error: 'XCTestExpectation' initializer is inaccessible due to 'internal' protection level
I apparently can't trust the online documentation on XCTestExpectation since it must only be valid for Apple platforms?
I dug through a bit of Swift/SwiftPM source code but I'm not really sure where is the "correct" place to look at and all the places where I did find XCTestExpectation had the initializer declared public (with default values) so I'm really confused as to why it works on my Mac but not Linux. There were also some additional helper methods for adding expectation to an XCTestCase, but none of them compiled on my mac.
Aciid
(Ankit Aggarwal)
2
I don't think we have XCTWaiter on Linux. /cc @Honza_Dvorsky
Ponyboy47
(Jacob Williams)
4
So does this basically mean I just can't use XCTestExpectation on linux until the next swift release?
zwaldowski
(Zachary Waldowski)
5
I have a few projects shared between Mac and Linux that use the XCTestCase.expectation(description:) and XCTestCase.wait(for:timeout:) methods to do what XCTestExpectation and XCTWaiter offer.
1 Like
Ponyboy47
(Jacob Williams)
6
@zwaldowski would you happen to have an example of how to use the XCTestCase.wait? Using both XCTestCase.wait(for: ..., timeout: ...) and self.wait(for: ..., timeout...) result in a has no member 'wait' error.
I did manager to get the expectation created on Linux though, so thank you for that pointer! 
levivic
(Leo)
7
would you mind sharing how to use them on Linux? I have the following code
import Foundation
import XCTest
class Test : XCTestCase{
static public func test_taskError() {
let urlString = "http://127.0.0.1:-1/Nepal"
let url = URL(string: urlString)!
let session = URLSession(configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: nil)
var completionExpectation = expectation(description: "GET \(urlString): Bad URL error")
let task = session.dataTask(with: url) { (_, _, result) in
let error = result as? URLError
XCTAssertNotNil(error)
XCTAssertEqual(error?.code, .badURL)
completionExpectation.fulfill()
}
//should result in Bad URL error
task.resume()
waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
XCTAssertNotNil(task.error)
XCTAssertEqual((task.error as? URLError)?.code, .badURL)
}
}
}
Test.test_taskError()
However it's giving me the following error:
simple.swift:12:37: error: instance member 'expectation' cannot be used on type 'Test'
var completionExpectation = expectation(description: "GET (urlString): Bad URL error")
^~~~~~~~~~~
simple.swift:22:9: error: instance member 'waitForExpectations' cannot be used on type 'Test'
waitForExpectations(timeout: 5) { error in
Not sure if it helps, but Nimble has built-in support for async expectations. We use it in some places and seem to have no problems with it on Linux.