
This video is only available to subscribers. Start a subscription today to get access to this and 469 other videos.
Refactoring Tests - Using #file and #line to indicate failure location
This episode is part of a series: Testing iOS Applications.
Extracting common test logic
Since most of our tests are performing the same operations (set up an expectation, wait for the response to come back, etc) we have a lot of duplication in our tests.
We can extract this code into a new home:
extension CryptoCompareClient {
func testFetchCoinListVerifyingResponse(resultBlock: @escaping (ApiResult<CoinList>) -> Void) {
let exp = XCTestExpectation(description: "Received coin list response")
fetchCoinList { result in
exp.fulfill()
resultBlock(result)
}
let result = XCTWaiter.wait(for: [exp], timeout: 3.0)
switch result {
case .timedOut:
XCTFail("Timed out waiting for coin list response")
default:
break
}
}
}
Note the use of the XCTestExpectation
and XCTWaiter
classes, which are now required because we are no longer in a test instance.
This can help clean up our tests, but there's a problem with this:
Failures will be reported in the helper method, not the failing test.
This is an issue, especially if this method is reused for multiple tests.
In order to zero in to the actual failing test, we need to carry the failure back to the place where we called that method.
That's where some helpful expression literals come in handy.
Introducing #file and #line
The Swift compiler gives us a handy automatic expansion of two important pieces of data:
- The current file
- The current line number
We can pass this along to XCT assertion methods and this will influence where the error is reported.
func testFetchCoinListVerifyingResponse(file: StaticString = #file, line: UInt = #line, resultBlock: @escaping (ApiResult<CoinList>) -> Void) {
//...
}
Note the two additional arguments to this method. They have default values of #file
and #line
respectively. This means they will be automatically populated with values at the call site.
We then update our assertions:
XCTFail("Timed out waiting for coin list response", file: file, line: line)
And now when our tests fail, they fail in the test, and not in a helper.