构建iOS单元测试的四个简单规则

您已经知道什么是单元测试,并且您可能已经在自己的iOS应用中编写了其中的一些测试。 那很棒! 现在,我们将进一步了解单元测试的结构。

当以某种方式编写单元测试时,它们是最有效的。 目标是以一种有组织的方式隔离组件和行为,从而使您深入了解应用程序的哪些部分有效,哪些无效。 只需一点技巧,您就可以编写单元测试来帮助您诊断问题,从而节省了比花费更多的时间。

这是创建测试套件时应遵循的最佳实践的简单列表。

隔离组件

好的单元测试不会尝试一次全部测试。 它一次测试一个组件的一种行为。

这是一个简单的经验法则。 每个要测试的组件都应该有一个XCTestCase文件。 该组件的所有测试都在该文件中。

在我的一个项目中,我有一个类来验证用户在文本字段中键入的薪资。 我将其称为PayrateValidator ,并将其命名为PayrateValidator.swift

在相应的测试套件中,测试PayrateValidator的XCTestCase子类称为PayrateValidatorTests ,包含该文件的文件称为PayrateValidatorTests.swift

这样一来,您也可以轻松地发现应用程序的哪些部分未被单元测试覆盖。 如果没有相应的测试用例文件,则很有可能没有该组件的单元测试 。 您还可以使用Xcode的测试覆盖率工具,我们将在另一篇文章中进行介绍。

关键是要有某种命名约定,以便您知道哪些文件可以测试什么。

等待。 我没有像这样的小组件。 我该怎么办?

对于初学者的iOS开发人员而言,这可能很难。 如果您没有MVC或MVVM等设计模式的经验,则您的应用程序可能没有任何隔离的组件。 您可能拥有一个巨型视图控制器,其中包含所有应用程序功能。

没办法判断。 我们都必须从某个地方开始。 我自己写了很多庞大的视图控制器。

编写好的单元测试的关键是要理解,您需要将应用程序分解成可以测试的较小部分 。 例如,如果视图控制器进行网络连接,请提取该逻辑并创建一个可以测试的单独的网络服务组件。

如果您不知道从哪里开始,请继续阅读一些常见的iOS应用程序设计模式,例如MVC或MVVM。 只需遵循这些步骤,您就会自动获得一个具有单独组件的应用程序,与庞大的视图控制器相比,这些组件更容易进行单元测试。

隔离行为

假设您已经隔离了一个组件。 您有一个与其关联的XCTestCase文件。 凉! 现在您需要测试。

结构良好的单元测试套件将每个组件分解为行为,每个行为都有其自己的功能来测试它们。

假设您正在编写Rick Astley的人工智能版本。 只是奠定基础,您可以像这样模拟他的一些行为。

这必须是Rick Astley的最笨拙的AI版本,但是也许这是您永远需要的所有编程。

在您的测试用例中, 通用约定是在单独的函数中测试不同的行为 。 它应如下所示。

在这里,我们只是断言,Rick Astley的每个属性都需要设置为false。 如果将这些属性中的任何一个设置为true,则测试将失败(并且您的少年心将碎裂)。

我知道这是一个有点过分简化的例子。 在真实的应用程序中,您将需要测试更复杂的行为。 我只是想向您展示一个干净的单元测试用例文件。

确实包含逆行为,也称为负面测试案例

通常,创建组件时,仅测试一个特定的输入或路径是不够的。 您需要测试多个输入和路径,以更全面地了解组件的实际行为。

您想知道您的组件执行了应该执行的操作, 并且也执行了不应该执行的操作

这是一个简单的Alarm类。 您给它一个触发时间,给它传递一个日期,它将告诉您是否应该触发。 另外,如果警报已经触发一次,则不会再次触发。

在单元测试用例中,您想考虑使用此组件的所有可能方式。

如果当前时间在触发日期之前怎么办? 警报应该触发吗? (不)

如果警报已经触发一次怎么办? 是否应该再次触发? (不)

因此,您的测试用例应涵盖所有这些基础。 这是此警报类别的相应单元测试用例文件。

我知道一次要编写很多代码。 忍受我 大多数代码只是设置一些模拟日期。

  1. 要设置测试,请选择一些任意的触发时间 。 使用日期组件,您可以将其指定为秒。
  2. 然后,要测试警报将触发,请在启动后立即选择片刻 。 我喜欢在开始时间之后再选择一秒钟。
  3. 要测试否定情况,请在开始时间之前选择片刻 。 任何时候都可以。 您只想知道您的闹钟可以正常工作。

如果您特别细心,您会发现我错过了一个测试用例。 如果没有触发时间(也就是将其设置为nil),则警报应如何处理? 编写一个测试案例并将其发布在评论中!

做描述性的

最后一点。 您是否注意到这些方法中的每一个似乎都有一个冗长的名称? 那是故意的 。 测试应尽可能详细地描述正在测试的内容以及组件的预期行为。

一组结构良好的单元测试应充当文档

您只需阅读测试名称就能理解您的组件如何工作。 您为正确命名这些方法投入的时间越多,拥有并运行测试套件所获得的实用程序就越多。

下一步是什么?

这涵盖了所有单元测试的工作。 在下一篇文章中,我将讨论一些应避免的事情。

同时,您可以查看其他一些单元测试文章。

我们应该在iOS应用程序中进行哪些单元测试?

教程:如何在iOS应用中对私有方法进行单元测试。

我目前正在写有关iOS单元测试的书。 如果您有任何要我讲的建议或主题,请给我发电子邮件。