【问题标题】:When to use unit tests? [closed]何时使用单元测试? [关闭]
【发布时间】:2012-10-03 18:55:19
【问题描述】:

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

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

【问题讨论】:

标签: iphone ios unit-testing


【解决方案1】:

理想世界的回答会说每一行你编写的代码都应该进行单元测试。

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

这种差异从何而来?两个主要原因:

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

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

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

再一次,你可能想问“线路在哪里?”你什么时候决定“好吧,这段代码的单元测试真的不需要”?不幸的是,这种判断来自经验。编写代码,阅读代码,看看其他人(可能更有经验的开发人员)做什么和学习。

如果我要给出几个通用的建议(单元测试的内容),这些建议是:

  • 从业务/域逻辑代码开始
  • 确保测试所有类型的转换器/解析器/计算器(这些转换器/解析器/计算器相当容易测试,往往会经常更改[由于需求变化或重构],而且它们的性质很容易出错)
  • 避免测试简单的单行方法,除非某行在某些方面至关重要
  • 为您发现的错误编写测试(并保留它们!)
  • 不要盲目地遵循“好的代码必须有 99.99% 的测试覆盖率”的神奇童话
  • 阅读questionson topicprogrammers.stackexchange.com 通常可以为您提供不同的视角来解决问题

【讨论】:

  • +1 - 我喜欢这个 - 写得很好!
【解决方案2】:

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

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

  • 提醒控制器

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

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

【讨论】:

【解决方案3】:

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

这样你就知道了几件事:

答:您的提醒生成正在工作

B:您存储数据的方法有效

C:从数据转到您的提醒对象正在工作

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

【讨论】:

    【解决方案4】:

    我在选择编写什么类型的测试以及何时编写测试时遵循以下原则:

    • 专注于编写端到端测试。与单元测试相比,您在每个测试中覆盖的代码更多,因此可以获得更多的测试收益。让这些成为整个系统的基本自动化验证。

    • 围绕复杂逻辑块编写单元测试。在端到端测试难以调试或难以编写的情况下,单元测试是值得的足够的代码覆盖率。

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

    Rob Ashton 有一个关于这个主题的 fine article,我大量引用该主题来阐明上述原则。

    【讨论】:

    • “等到你测试的 API 稳定”——这违背了 TDD 的主要好处之一,即你的测试是你的 API 的第一个客户端,根据我的经验,这会导致很多比在生产代码之后编写测试时更好的 API。
    • @Frank:我同意您希望编写足够多的代码来磨练您的 API 的可用性。也许它是单元测试的形式,但也许它是你必须编写的其他实现代码,或者其中一些。无论如何,重点应该是实际使用。为了最大程度地减少返工,请只编写验证 API 设计所需的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2011-11-07
    • 2010-12-21
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多