了解不稳定的iOS单元测试:XCTestCases基础知识

曾经试图弄清楚为什么单元测试随机失败了吗? 试图解决这些问题时花了很多血汗和眼泪? 对于我从事的许多较大的长期项目来说,不稳定的单元测试是一个真正的问题。 他们占用了时间和精力,而这可以在其他地方得到最好的利用。 我已经看到一些公司禁用了许多测试,从而在测试服中留下空白,在某些极端情况下,由于事情太重了,删除了整个测试服。

我是一个测试狂,我喜欢这些东西,多年来,我学到了一些我想分享的技巧。 我希望其中一些可以使您摆脱我遇到的同样的陷阱。

但是,在深入了解细节之前,让我们退后一步,首先看看XCTestsCases是如何工作的。 不了解这些测试的流程会导致我遇到的大部分问题。

XCTestCase流程

了解XCTestCase流程的最好方法是运行以下测试代码,并在测试运行后查看调试(“ >>>”在那里,您可以进行过滤并轻松查看流程)。

在示例代码中,测试类ExampleTestCase包含一个Object和两个测试函数testExampleAtestExampleB (在此示例中,我们对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测试不稳定