在运行某些单元测试时不一致地得到此错误:
2018-12-20 09:11:34.892 MyApp [4530:106103] *无效_XCTFailureHandler(XCTestCase *断言失败__No _Nonnull,BOOL,const char * _Nonnull,NSUInteger,NSString * __ strong _Nonnull,NSString * __strong _Nullable,...)(),/Library/Caches/com.apple.xbs/Sources/XCTest_Sim/XCTest-14460.20/Sources/XCTestFramework/Core/XCTestAssertionsImpl.m:41 2018-12-20 09:11:34.929 MyApp [4530:106103] * 由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'参数“ test”不能为零。'
似乎某个断言失败了,因为参数为nil
,但是我很难确定哪个参数。
环境: Xcode 10.1 iOS应用程序
答案 0 :(得分:0)
XCTest
声明将抛出此异常:
由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“参数“ test”不得为零。”
证明这一点的一个基本示例是以下测试:
func testRaceCondition() {
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 3) // Assertion fails and 'nil' exception is thrown
}
}
断言是异步运行的,但是测试不会等待异步块完成。因此,在评估断言时,测试已经完成并且测试用例已经发布(因此为nil
)。
如果断言通过,上面的代码将不会引发任何错误。以下代码似乎可以通过测试,但是从失败的意义上讲,失败会引发以上异常,而不是使测试未能正确通过,这是危险的:
func testRaceCondition() {
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 2) // Assertion passes
}
}
为防止出现此问题,所有评估异步执行的块中的断言的测试都应使用期望值,并等待它们完成:
func testRaceCondition() {
let asyncExpectation = expectation(description: "Async block executed")
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 3)
asyncExpectation.fulfill()
}
waitForExpectations(timeout: 1, handler: nil)
}
通过使用期望,我们将获得适当的测试失败错误,而不是上面发布的难以调试的异常:
XCTAssertEqual失败:(“ 2”)不等于(“ 3”)