首页 文章

TDD与单元测试[关闭]

提问于
浏览
116

我的公司对我们的代码进行单元测试是相当新的 . 我已经阅读了TDD和单元测试一段时间,并确信它们的 Value . 我试图让我们的团队相信TDD值得学习和改变我们的编程思路,但这是一场斗争 . 这让我想到了我的问题 .

TDD社区中有很多人非常虔诚地写测试然后编写代码(我和他们在一起),但是对于正在与TDD斗争的团队来说,妥协仍然会带来额外的好处吗?

编写代码后,我可能成功让团队编写单元测试(可能是检查代码的要求),我的假设是编写单元测试仍然有 Value .

将陷入困境的团队带入TDD的最佳方式是什么?如果失败的话,即使代码写完之后仍然值得编写单元测试吗?

EDIT

我从这里得到的是,在编码过程中的某个地方开始进行单元测试非常重要 . 对于那些接受概念的团队成员,开始更多地转向TDD并首先进行测试 . 感谢大家的投入 .

FOLLOW UP

我们最近开始了一个新的小项目,并且团队的一小部分使用了TDD,其余的在代码之后写了单元测试 . 在我们完成了项目的编码部分之后,那些编写单元测试代码的人员惊讶地看到TDD编码器已经完成并且代码更加扎实 . 这是赢得怀疑论者的好方法 . 我们仍然有很多成长的痛苦,但意志之战似乎已经结束 . 感谢所有提供建议的人!

17 回答

  • 12

    如果团队正在实施TDD,但他们之前没有创建任何单元测试......那么在编写代码后创建单元测试就可以启动它们 . 甚至在代码之后编写的单元测试总比没有单元测试好!

    一旦他们精通单元测试(以及随附的所有内容),那么你可以先让他们创建测试......然后再编码 .

  • 3

    代码编写完成后仍然值得编写单元测试 . 只是有时它往往更难,因为你的代码不是为了测试而设计的,你可能会过于复杂 .

    我认为将团队纳入TDD的一种良好实用的方法是在过渡期或可能是长期内提供“在开发期间测试”的替代方法 . 应该鼓励他们使用看起来很自然的TDD代码段 . 但是,在代码部分似乎很难接近测试优先或使用由非敏捷A&D流程预先确定的对象时,开发人员可以选择编写一小部分代码,然后编写测试来覆盖代码,并重复此过程 . 在编写代码之后立即编写单元测试某些代码比完全不编写任何单元测试更好 .

  • 26

    我的拙见认为,使用"code first, test after"和100%完成的库可获得50%的测试覆盖率,而不是100%的测试覆盖率和50%完成的TDD库 . 过了一段时间,你的开发人员希望能够为他们编写的所有代码编写测试,这对于编写测试非常有趣和教育,因此TDD会潜入他们的开发程序 .

  • 2

    TDD是关于设计的!因此,如果您使用它,您将确保拥有可测试的代码设计,从而更容易编写测试 . 如果你在编写代码之后编写测试它们是 still valuable 但是恕我直言,你将浪费时间,因为你可能没有可测试的设计 .

    我可以给你一个建议说服你的团队采用TDD的建议是使用Mary Linn and Linda Rising book : Patterns for Introducing new Ideas中描述的一些技术

  • 4

    我只是在日历上看到这一点:“每一条规则,最大限度地执行,变得荒谬甚至危险 . ”所以我的建议是不要虔诚于此 . 您的团队中的每个成员都必须在测试时感觉“正确”之间取得 balancer . 通过这种方式,团队中的每个成员都将获得最高效率(而不是说,思考“为什么我必须编写这个测试?”) .

    所以有些测试总比没有好,代码之后的测试比代码优于之后的测试和测试要好 . 但是每一步都有其自身的优点,你不应该对任何小步骤不屑一顾 .

  • 1

    如果他们刚接触测试,那么IMO就会开始测试已经编写好的代码并慢慢毕业,先编写测试代码 . 当有人试图学习TDD和新的单元测试时,我发现很难做一个完整的180并改变我的思维方式在代码之前编写测试,所以我采取的方法是50-50混合;当我确切知道代码的样子时,我会编写代码,然后编写一个测试来验证它 . 对于我不完全确定的情况,我会从测试开始,然后向后工作 .

    还要记住,没有任何问题编写测试来验证代码,而不是编写代码来满足测试 . 如果您的团队不想使用TDD路线,请不要强行使用它 .

  • 4

    一旦编写代码,我可能成功让团队编写单元测试(可能是检查代码的要求),我的假设是编写单元测试仍然有 Value .

    毫无疑问,单元测试代码中存在 Value (无论何时编写测试),并且我在“完成定义”中包含“代码已经过单元测试” . 人们可以使用TDD,只要他们测试 .

    关于版本控制,我喜欢使用带有 unit tested 策略的“开发分支”(即代码编译和构建,所有单元测试都通过) . 功能完成后,它们将从开发分支发布到主干 . 换句话说,主干分支是“完成分支”(主干上没有垃圾!)并且有一个 shippable 策略(可以随时释放),它更严格,包含的内容比"unit tested"更多 .

  • 3

    这是你的团队在开始相信它之前必须有自己的成功的事情 . 我会为任何关心的人咆哮我的nUnit顿悟:

    大约5年前,我在一个项目上发现了nUnit . 我们差不多完成了V1.0,我创建了一些测试来试用这个新工具 . 我们有很多错误(显然!)因为我们是一个新的团队,在一个紧迫的期限,高期望(听起来很熟悉?)等等 . 无论如何我们得到1.0并且从1.1开始 . 我们重新组建了一些团队,并为我分配了2个开发人员 . 我为他们做了一个1小时的演示并告诉他们我们写的所有东西都必须有一个测试用例 . 在1.1开发周期期间,我们不断地在团队的其他成员后面跑,因为我们编写了更多的代码,单元测试 . 我们最终工作得更多,但这里是收益 - 当我们最终进入测试时,我们的代码中只有0个错误 . 我们帮助其他人调试和修复他们的错误 . 在死后,当虫子计数出现时,它引起了所有人的注意 .

    我并不愚蠢到认为你可以测试你的成功之路,但在单元测试中我是一个真正的信徒 . 该项目采用了nUnit,并且由于成功,它很快就传播到公司所有.Net项目 . 我们V1.1发布的总时间为9个星期,因此绝对不是一夜之间的成功 . 但从长远来看,它证明了我们的项目和我们为其 Build 解决方案的公司是成功的 .

  • 3

    毫无疑问,测试(首先,甚至是之后)将节省您的培根,并提高您的 生产环境 力和信心 . 我建议采用它!

    我处于类似的情况,因为我是一名“noob”开发人员,因为贡献破坏了构建,我在团队项目工作时经常感到沮丧 . 我不知道是否应该责备,甚至在某些情况下,应该责怪谁 . 但是我更担心的是我和其他开发人员做同样的事情 . 然后,这种认识促使采用一些TDD策略 . 我们的团队开始有愚蠢的游戏和规则,就像你在所有测试通过之前都无法回家,或者如果你提交没有测试的东西,那么你必须购买所有人“啤酒/午餐/等”,这使TDD更有趣 .

  • 9

    单元测试最有用的方面之一是确保已经正常工作的代码的持续正确性 . 当您可以随意重构时,让IDE提醒您编译时错误,然后单击按钮让您的测试发现任何潜在的运行时错误 - 有时会到达以前微不足道的代码块,然后我认为您会找到您的团队开始欣赏TDD . 因此,从测试现有代码开始肯定是有用的 .

    另外,直言不讳地说,通过尝试测试编写代码而不是从TDD开始,我学到了更多关于如何编写可测试代码的知识 . 如果你想要的是能够实现最终目标并允许测试的 Contract ,那么它起初可能过于抽象 . 但是当你看到代码并且可以说“这里的单身完全破坏依赖注入并使测试变得不可能”时,你就开始了解哪种模式可以让你的测试生活更轻松 .

  • 2

    好吧,如果你不写测试第一,它不是“测试驱动”,它只是测试 . 它本身就有好处,如果你已经有了代码库,那么即使它不是TDD而只是测试,添加测试肯定是有用的 .

    首先编写测试是关注代码在编写之前应该做什么 . 是的,你也做了一个测试,这很好,但有些人可能认为这甚至不是最重要的一点 .

    我要做的是使用TDD训练团队toy projects like these(参见Coding Dojo,Katas)(如果你能让经验丰富的TDD程序员参加这样的研讨会,那就更好了) . 当他们'll see the benefits they will use TDD for the real project. But meanwhile do not force them, it they do not see the benefit they won' t做对了 .

  • 3

    如果您在编写代码之前有设计会话或必须生成设计文档,那么您可以添加单元测试作为有形结果 Session .

    然后,这可以作为您的代码应如何工作的规范 . 鼓励在设计 Session 上进行配对,让人们谈论某些事情应该如何运作以及在给定的场景中应该做些什么 . 什么是边缘情况,为它们提供明确的测试用例,以便每个人都知道如果给出一个null参数,它将会做什么 .

    除此之外,BDD也可能是有意义的

  • 16

    您可以通过显示一个或两个示例来获得一些牵引力,其中TDD导致编写的代码更少 - 因为您只编写了使测试通过所需的代码,金板或参与YAGNI的诱惑更容易抵抗 . 你不写的代码不需要维护,重构等,所以这是一个“真正的节省”,可以帮助销售TDD的概念 .

    如果您可以清楚地证明在时间,成本,代码和保存的错误方面的 Value ,您可能会发现它更容易出售 .

  • 6

    开始构建JUnit测试类是开始的方法,对于现有代码,它是唯一的启动方式 . 根据我的经验,为现有代码创建测试类非常有用 . 如果管理层认为这会投入太多时间,那么您可以建议仅在发现相应的类包含错误或需要清理时才编写测试类 .

    对于维护过程,让团队超越线路的方法是编写JUnit测试以在修复之前重现bug,即

    报告

    • 错误

    • 如果需要,创建JUnit测试类

    • 添加一个重现该bug的测试

    • 修复你的代码

    • 运行测试以显示当前代码不会重现该错误

    你可以解释一下,以这种方式“记录”错误可以防止这些错误在以后再次出现 . 这是团队可以立即体验的好处 .

  • 2

    我已经在许多组织中完成了这项工作,我发现启动TDD的最佳方法是设置结对编程 . 如果你有其他人可以指望知道TDD,那么你们两个可以分开并与其他开发人员配对,实际使用TDD进行一些配对编程 . 如果不是,我会训练有人帮助你做这个,然后再提交给团队的其他成员 .

    单元测试,特别是TDD的主要障碍之一是开发人员不知道如何去做,所以他们看不出它是如何值得花时间的 . 此外,当你刚开始时,它要慢得多,似乎没有提供好处 . 只有当你擅长时才真正为你提供好处 . 通过设置成对的编程会话,您可以快速让开发人员快速学习并快速掌握它 . 此外,当您一起工作时,他们将能够立即从中获益 .

    过去,这种方法对我来说已经有很多次了 .

  • 12

    发现TDD优势的一种有效方法是对某些现有功能进行重大改写,可能是出于性能原因 . 通过创建一套能够很好地覆盖现有代码的所有功能的测试,您可以放心地重构内容,并确信您的更改是安全的 .

    请注意,在这种情况下,我正在谈论测试设计或 Contract - 测试实现细节的单元测试在这里不合适 . 但话说回来,TDD无法按定义测试实现,因为它们应该在实现之前编写 .

  • 74

    TDD是开发人员可以用来生成更好代码的工具 . 我碰巧认为编写可测试代码的练习至少与测试本身一样有 Value . 为了测试目的而隔离IUT(被测实施)会产生解耦代码的副作用 .

    TDD并不适合每个人,并且没有任何魔法会让团队选择这样做 . 风险在于,不知道什么值得测试的单元测试编写者会编写大量的低 Value 测试,这将成为组织中TDD怀疑论者的炮灰 .

    我通常使自动验收测试不可协商,但允许开发人员采用适合他们的TDD . 我有经验丰富的TDDers培训/指导其余部分,以及在几个月的时间内通过实例的有用性 .

    这既是一种社会/文化变革,也是一种技术变革 .

相关问题