【问题标题】:How often should we write unit tests?我们应该多久编写一次单元测试?
【发布时间】:2011-02-02 00:57:29
【问题描述】:

我的导师最近在工作中向我介绍了测试驱动的开发方法,他鼓励我在“有意义”时编写单元测试。我理解为回归测试和重构提供完整的单元测试套件的一些好处,但我确实想知道我们应该多久以及如何编写单元测试。

我的导师/开发负责人要求我为新编写的控制流编写一个新的单元测试用例,该方法已由现有测试类进行测试,我认为这太过分了。你多久编写一次单元测试,你认为你的单元测试应该有多详细?谢谢!

【问题讨论】:

  • 这真的是 TDD,还是只是单元测试?

标签: java unit-testing tdd


【解决方案1】:

从技术上讲,如果您遵循严格的测试驱动开发...您应该在指定应用程序的任何部分之后编写单元测试。你应该从:

用户需求 -> 功能设计 -> 单元测试 -> 代码

记住,在 TDD 中测试先于代码

【讨论】:

  • 还有一个很好的插图:blog.typemock.com/2008/12/…
  • -1:如果您遵循严格的测试驱动开发,代码是在 Test(单数)-> 代码-> 重构-> 循环中生成的另一个Test,不是代码之前的所有测试。
【解决方案2】:

正如贾斯汀所说,您应该在编写代码之前编写单元测试。

虽然这可能是最好的做法,但有时也有些矫枉过正。根据项目的不同,我有时只为我发现(并解决)的每个错误编写一个单元测试。

当然,我可能会错过其中的一些,但是随着时间的推移,我的单元测试变得越来越高效,而且我很确定我永远不会错过一个更正的错误。

【讨论】:

    【解决方案3】:

    单元测试应该让您有信心,您编写的代码可以满足您的需求。因此,您应该编写尽可能多的测试来给您这种信心。

    【讨论】:

      【解决方案4】:

      单元测试将:

      • 让您有信心进行重构更改,同时知道您不会破坏其他任何东西。
      • 充当代码的一种“活文档”,让其他人准确了解代码在各种情况下的行为方式。
      • 当遵循@Justin 所描述的严格 TDD 时,通过在开始编写代码之前编写的所有单元测试将让您知道何时“完成”编码。根据我的经验,这也可以大大简化和更容易理解(更干净)的代码。

      正如您的导师所说,您应该只编写有意义的单元测试。我使用的经验法则是我尝试为执行业务逻辑的代码段编写单元测试。我通常不会为只有 getter 和 setter 的 bean 类编写单元测试。

      随着时间的推移,单元测试通常会变得更有价值,因为它们被扩展和增强以处理错误修复和在初始交付后进行的其他代码增强。

      【讨论】:

        【解决方案5】:

        每当您编写任何代码时,您都应该编写单元测试。而且,正如其他人指出的那样,在 TDD 中,您在编写代码之前编写测试

        如果你认为这太过分了,问问自己“如果我不测试这段代码,我怎么知道它有效?”

        【讨论】:

        • 唯一的问题是编写测试并不能告诉你它也有效,只是它通过了你想到的任何测试。
        • @darron 这就是您将测试基于功能设计的原因。测试告诉你它符合要求。
        • ... 但重点仍然存在,如果您不为刚刚添加的代码块编写测试,您将无法知道它是否有效。至少,如果您编写了测试,您可以证明它根据某些规范(规范是,测试检查的内容)工作。
        • @darron 我不同意:如果您只编写满足您的测试的代码,仅此而已,您的测试从定义上就成为规范。这意味着您不仅拥有“您碰巧想到的”测试……您的测试定义了您的代码应该做什么,而您的代码实际上仅此而已!您的评论更适合“事后”编写单元测试:您确实没有想要的安全性。
        • @Epaga:对不起,这太荒谬了。假设开发人员是一个新手,他从未听说过某些语言环境会颠倒“,”和“。”。在数字字段中。甚至首先编写测试,并且只对测试进行编码......他的测试都会通过!这仍然是一个错误,当它出现时,您不可能期望告诉客户“它按规定工作”。这是一个简单的示例问题,但仔细考虑意味着 TDD 根本不可能让您“知道”任何事情……除了它似乎通过了 您碰巧想到的测试这一事实> 并且希望你写的正确。
        【解决方案6】:

        在进行测试驱动开发时,单元测试有一个基本原则,即单元测试描述功能。如果测试没有定义例如空输入如何表现,那么你不能指望它工作。

        【讨论】:

          【解决方案7】:

          编写测试,更重要的是可测试代码是一项独立技能,就像学习编程每种新语言是一项独立技能一样。

          阅读 Miško Hevery 的博客,阅读一些书籍(我喜欢 Lasse Koskela 的 Test Driven),使用一些代码覆盖率工具,例如 Clover,然后编写一些测试。

          随着您编写测试,您的测试技能将会提高,并且您将开始了解编写可测试代码所涉及的内容。然后,您将能够了解您的特定项目所需的代码覆盖率级别。

          【讨论】:

            【解决方案8】:

            我的导师/开发主管要求我为新编写的控制流编写一个新的单元测试用例

            除非需要通过失败的测试,否则该控制流是如何编写的?通过definition of TDD,将不会出现任何生产代码,除非首先存在需要编写该段代码的失败测试。所以你一定是在使用一些最后测试的技术而不是 TDD 来编写代码。

            我建议您阅读文章The Art of Agile Development: Test-Driven Development。您可以使用this tutorial 练习 TDD。

            我认为你的导师使用“只要有道理”这个短语可能是有害的,尤其是对 TDD 新手来说,因为在拥有多年经验之后,一个人不可能做出正确的决定,之后一个已达到Ri-level。有一次,Kent Beck decided to not write a test,Ron Jeffries 恰如其分地评论道:“我相信你和其他三个人,能够做出好的短杆决定。”

            你应该总是先写一个测试。任何可能破坏的东西都需要进行测试。只有由于有人更改代码而永远不会破坏的东西才不需要测试。例如,声明式代码很少中断:网页上的静态 HTML 布局代码通常不值得自动测试(您必须手动测试它是否看起来正确),但任何动态的都值得测试。

            【讨论】:

              【解决方案9】:

              如果您现有的测试套件不足,您应该始终编写测试。最好的迹象是,您的测试还不够,这是错误。因此,一个好的做法是为遇到的每个错误编写一个单元测试。对于测试驱动的开发,您应该从一些测试开始,定义一个类的功能。 test-coverage-tools 为您提供一些提示,哪些部分可能需要更多测试。

              【讨论】:

                【解决方案10】:

                这个问题的正确/彻底答案必须很长,因为这是每个测试过程的关键问题,但我会用以下简单(?)规则来回答:

                1. 如果某个用例重要为其编写单独的测试,以便其他人(或将来的您)可以通过阅读或未通过测试来发现该用例。

                2. 如果您想知道某件事是否重要足以进行测试,超过 5 秒,那么假设它是 :-)

                3. 如果有任何机会测试此案例非常困难/昂贵,请向您的经理/技术主管投诉并跳过编写测试。

                【讨论】:

                  【解决方案11】:

                  我个人使用单元测试,当我有大量数据时,我不想复制/粘贴很多 System.out.println,并一对一地检查它们。 使用单元测试,您会损失 1 小时来编写它们,并节省大量测试时间。对于琐碎的东西,我宁愿使用 println 技术,或者检查调试变量。

                  【讨论】:

                    【解决方案12】:

                    我最近也成为了 TDD 的转换者,我发现它非常有帮助。这个想法是,一旦你有了一个规范,你就开始编写单元测试。编写完测试后,大部分代码都可以来自这些测试。你的测试中剩下的是你的断言的基础,然后你就有了一个非常好的可重复模式——编写测试、实现代码、通过断言确认、继续。好东西!

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2021-08-08
                      • 1970-01-01
                      • 2011-02-22
                      • 2012-08-11
                      • 2013-08-07
                      • 2010-10-05
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多