编写用例时注意
1.用例只针对 SDK 对外开放的入口
2.注意异常情况和边界值
3.注意用例之间的依赖情况
单测用例如何按照顺序执行
测试函数的执行顺序与测试的字符大小有关系,如- (void)test001Example > - (void)test002Example > - (void)testExample
理论上单元测试不应该控制用例的执行顺序,每个 case 都能够单独执行,但是针对某些特殊的情况,可以适当使用一次此特性。
用例依赖的情况如何处理
当你的用例需要按照顺序执行就说明你的用例存在依赖,针对这种情况就需要进行拆分,放到不同的组(测试文件)当中来执行,比如说存在 a,b,c 三个用例,b 和 c 都依赖于 a,那么比较合理的做法就是将 a 提到另外一个文件当中进行测试,b 和 c 放到另外一个文件中,在 b 和 c 的文件中将 a 放入 setUp 方法用作 b、c 执行的前提,这样就能比较好的进行测试,也减少了大量的冗余代码。
multiple calls made to -[XCTestExpectation fulfill]
出现这种情况是因为写在回调当中的 XCTestExpectation 被多次调用导致的,解决这个错误,网上目前有以下三种解决方案,可以根据自己的情况进行选择:
1.使用 __weak 修饰 XCTestExpectation。
[expectation fulfill] 执行一次后方法执行完毕,局部变量 expectation 被释放,当回调再次调起时,expectation 已被释放置 nil,执行 fulfill 不会报错。
1 | - (void)testExample { |
但是该种方法存在一个问题,就是当有多个 XCTestExpectation 时,靠前的 expectation 执行 fulfill 时,该方法并不一定结束,导致再次调用 fulfill 报错,如下当 noticeExpectation 所在的回调被第二次调用时,expectation 可能并未 fulfill,变回导致 noticeExpectation 多次 fulfill 报错。
1 | - (void)testExample { |
2.使用 __block 修饰 XCTestExpectation 并在 fulfill 之后置为 nil
当 XCTestExpectation 对象执行过 fulfill 之后被置为了 nil,再次调用 fulfill 则不会报错。
1 | - (void)testExample { |
这种方法在大部分情况可以可以解决问题,有种特殊的情况我们后面再讨论
3.移除回调的多次调用逻辑。
查找并移除回调多次调用的逻辑是从根本上解决这种问题的方法,但是某些业务场景下我们可能是需要回调多次调用的,针对这种情况,我们就可以采用第二种方法来解决问题。
超时之后 fulfill 错误无法上报
这种错误是因为等待 XCTestExpectation 超时测试方法执行完毕后,回调调用(比如网络不好超时的情况),而且返回了一个错误的结果,在回调当中的断言失败却无法上报错误导致的崩溃,错误信息大致如下:
1 | Terminating app due to uncaught exception 'NSInternalInconsistencyException', |
这种错误在上面提到的使用 __block 的情况下也不能幸免,解决方案就是使用一个 __block 修饰的变量,将回调当中要获取的值取出来,然后再外层进行数据判断,这样就不会导致断言在回调当中崩溃了。
1 | - (void)testExample { |
Assertion failure in -[XCTestExpectation fulfill]
这个错误是当有多个 XCTestExpectation 时使用 waitForExpectations:timeout: 等待 Expectation 导致,导致错误的具体原因目前还不是很明确,有了解具体原因的同学可以告诉我下。
针对这个问题,我们可以使用 waitForExpectationsWithTimeout:handler: 来等待 Expectation,这样就不会报错了。
attempt to insert nil object from objects[0]
这个错误是因为我们在前面使用 __block 修饰 XCTestExpectation 并置为 nil 操作的解决方案时同时使用了 waitForExpectations:timeout: 来等待 Expectation,向数组中插入了 nil。
这个问题的解决方案同上,使用 waitForExpectationsWithTimeout:handler: 来替换即可。所以针对大多数啊情况推荐使用 waitForExpectationsWithTimeout:handler: 来等待 XCTestExpectation。