XCTest:由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“参数“ test”不能为零。

时间:2018-12-20 17:51:01

标签: xcode unit-testing xctest

在运行某些单元测试时不一致地得到此错误:

  

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应用程序

1 个答案:

答案 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”)