何时使用单元测试?

时间:2012-10-03 18:55:19

标签: iphone ios unit-testing

我理解如何实现单元测试,我只是在努力弄清楚何时使用它们。

假设我有一个基本的提醒应用程序。用户可以添加/编辑/删除提醒并在桌面视图中查看它们。我想为应用程序的哪些部分设置单元测试?

4 个答案:

答案 0 :(得分:6)

理想世界答案会说您编写的代码的每一行应该经过单元测试。

但是让我们暂时忘掉这一点,然后回到现实世界。为重要的代码编写测试并且另一道防线是值得的。换句话说,测试构造函数是否仅仅为一个字段赋值?很可能不是。是否值得单元测试解析器从客户端提供的复杂XML中提取帐户数据?可能是的。

这种差异来自哪里?两个主要原因:

  • 构造函数代码不太可能遭受不可预测的更改(与非常发展的解析器代码相比,以满足不断变化的需求/优化/重构)
  • 构造函数代码相当简单,你已经多次编写过这样的代码,测试可能无法为你发现问题提供巨大的优势;快速浏览一下这些代码,你很可能会知道发生了什么(与复杂的XML解析器代码相比)

为什么要区分?为什么测试这个而不是那个?简单地测试一切都不容易(正如理想世界答案所暗示的那样)?

没有。因为时间和金钱限制。编写代码需要两个。并且只有一些人愿意为你的产品支付一定数量的钱,就像他只有一定的时间等待它交付一样。有些测试根本不值得(再次,构造函数代码示例)。请记住,单元测试不能免于diminishing returns(测试覆盖80%的代码库可能需要额外20%的开发时间,以后节省20%的时间用于调试/维护,而另外10%可能是两次虽然耗时但产生的收益却小得多。)

同样,你可能想问“哪里有线?”你什么时候决定“好的,不需要对这段代码进行单元测试”?不幸的是,这种判断伴随着经验。编写代码,阅读代码,了解其他人(可能是更有经验的开发人员)做和学习的内容。

如果我要提供一些通用建议(单元测试),那将是:

  • 从业务/域逻辑代码开始
  • 确保测试所有类型的转换器/解析器/计算器(那些很容易测试,往往会因为不断变化的要求或重构而改变),并且其性质容易出错)
  • 避免测试简单的单线方法,除非那条线在某种程度上是至关重要的
  • 为您发现的错误编写测试(并保留它们!)
  • 不要跟随“好的代码必须具有99.99%的测试覆盖率”的魔法童话盲目地
  • questions阅读on topic programmers.stackexchange.com通常可以为您提供解决问题的不同视角

答案 1 :(得分:1)

假设您将提醒存储在某处,也许是在plist中。您可以编写单元测试来生成Reminder对象,存储它,检索数据,最后生成可用的Reminder类对象。

这样你就会知道几件事:

答:你的提醒一代正在运作

B:您存储数据的方法正在运行

C:从Data到你的Reminder对象正在运行

但是,您不应期望能够对应用程序的实际“功能”进行单元测试。如触摸事件或导航控件。这些应留给验收测试,这是一个完全不同的讨论。

答案 2 :(得分:1)

测试您编写的所有代码。如果你想变得很酷,write the test first。如果你在模型或控制器上有方法,你也应该对它进行测试。

在不了解您的代码的情况下,很难提供建议。但听起来你会有一个控制器(如RemindersController)和一个模型(如Reminder)。这将是我开始的基本概要:

  • RemindersController

    • 应添加新提醒
    • 应更新现有提醒
    • 应删除现有提醒
  • 提醒

    • initWithMessage:atTime:应设置消息
    • initWithMessage:atTime:应设置时间

答案 3 :(得分:0)

我遵循这些原则选择要编写的测试类型以及何时:

  • 专注于编写端到端测试。每次测试的代码覆盖次数多于单元测试代码,因此可以获得更多测试。将这些作为整个系统的自动验证。

  • 下载到编写复杂逻辑块的单元测试。在端到端测试难以调试或难以编写的情况下,单元测试非常重要。足够的代码覆盖率。

  • 等到您要测试的API稳定以编写任何类型的测试。您希望避免重构您的实现和测试。

Rob Ashton在这个主题上有一个fine article,我从中大量阐述了上述原则。