了解不稳定的iOS单元测试:XCTestCases基础知识
曾经试图弄清楚为什么单元测试随机失败了吗? 试图解决这些问题时花了很多血汗和眼泪? 对于我从事的许多较大的长期项目来说,不稳定的单元测试是一个真正的问题。 他们占用了时间和精力,而这可以在其他地方得到最好的利用。 我已经看到一些公司禁用了许多测试,从而在测试服中留下空白,在某些极端情况下,由于事情太重了,删除了整个测试服。
我是一个测试狂,我喜欢这些东西,多年来,我学到了一些我想分享的技巧。 我希望其中一些可以使您摆脱我遇到的同样的陷阱。
但是,在深入了解细节之前,让我们退后一步,首先看看XCTestsCases是如何工作的。 不了解这些测试的流程会导致我遇到的大部分问题。
XCTestCase流程
了解XCTestCase流程的最好方法是运行以下测试代码,并在测试运行后查看调试(“ >>>”在那里,您可以进行过滤并轻松查看流程)。
在示例代码中,测试类ExampleTestCase包含一个Object和两个测试函数testExampleA和testExampleB (在此示例中,我们对Object的作用并不真正感兴趣,只是其生命周期与XCTestCase有关)
这是输出…
>>>对象初始化0x0000600000b94290
>>>对象初始化0x0000600000b942d0
>>> testExampleA 0x0000600000b94290
>>> testExampleB 0x0000600000b942d0
这告诉我们什么?
在编写测试时,我们需要牢记此输出中的一些关键信息:
- 为每个测试功能创建一个ExampleTestCase对象,并且在运行任何测试之前首先创建所有对象。
- 测试按字典顺序运行,而不是按文件中表示的顺序运行。
- ExampleTestCase不会被释放,因此从不释放对象 。
这种流动如何影响稳定性?
作为开发人员,我们有各种各样的机会编写不稳定的测试。 后续帖子将更详细地介绍在过早创建对象并将其与诸如Observer和特定类型的Singletons等模式以及其他可能导致不稳定的事物(如UIWindow和UINavigationControllers。
对于简单的简短测试文件,您可以在测试函数中创建所有属性。 但是,随着事情变得越来越复杂,这可能变得很麻烦,因此最好在setUp中创建所有属性, 然后在tearDown中手动释放它们 。
我只在Objective-C测试中看到过此技巧,但是如果您已经进行了不稳定的测试,那么您可以做的第一件事就是释放tearDown中的所有内容,这有时会导致测试崩溃,方法是可能导致问题。
即使您没有任何不稳定的测试,也最好立即开始在tearDown中释放对象,以在出现任何潜在问题之前捕获它们。
您可以开始使用XCode10新功能对测试进行随机化,要记住您拥有的测试越多,随机组合就越多。 如果发生问题,您需要能够看到他们重新创建问题的顺序,因此请确保您的CI系统可以为您提供所需的信息。
在编写测试时,我们需要注意以下几点
- XCTestCase为每个方法创建一个新的测试类。
- 每个XCTestCase类及其所有属性都是在运行任何测试之前预先创建的。
- XCTestCase不会自动释放。
- 测试未按定义的顺序运行。
- 在setUp中创建XCTestCase属性,并在tearDown中手动释放
相关链接
NSNotifications测试不稳定