TDD与单元测试[已结束]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TDD与单元测试[已结束]相关的知识,希望对你有一定的参考价值。
我的公司对我们的代码进行单元测试是相当新的。我已经阅读了一段时间关于TDD和单元测试的信息并且确信它们的价值。我试图让我们的团队相信TDD值得学习和改变我们的编程思路,但这是一场斗争。这让我想到了我的问题。
TDD社区中有很多人非常虔诚地写测试然后编写代码(我和他们一起),但对于一个正在与TDD斗争的团队来说,妥协仍然会带来额外的好处吗?
编写代码后,我可能成功让团队编写单元测试(可能是检查代码的要求),我的假设是编写单元测试仍然有价值。
将陷入困境的团队带入TDD的最佳方式是什么?如果失败的话,即使代码写完之后仍然值得编写单元测试吗?
编辑
我从这里得到的是,在编码过程中的某个地方开始进行单元测试非常重要。对于那些接受概念的团队成员,开始更多地转向TDD并首先进行测试。感谢大家的投入。
跟进
我们最近开始了一个新的小项目,并且团队的一小部分使用了TDD,其余的在代码之后编写了单元测试。在我们完成了项目的编码部分之后,那些编写单元测试代码后,他们惊讶地看到TDD编码器已经完成并且代码更加可靠。这是赢得怀疑论者的好方法。我们仍然有很多成长的痛苦,但意志之战似乎已经结束。感谢所有提供建议的人!
如果团队正在实施TDD,但他们之前没有创建任何单元测试......那么在编写代码后创建单元测试就可以启动它们。甚至在代码之后写的单元测试总比没有单元测试好!
一旦他们精通单元测试(以及随附的所有内容),那么你可以先让他们创建测试......然后再编码。
单元测试最有用的方面之一是确保已经正常工作的代码的持续正确性。当您可以随意重构时,让IDE提醒您编译时错误,然后单击一个按钮让您的测试发现任何潜在的运行时错误 - 有时会到达以前琐碎的代码块,然后我认为您会找到您的团队开始欣赏TDD。所以从测试现有代码开始肯定是有用的。
另外,直言不讳地说,通过尝试测试编写代码而不是从TDD开始,我学到了更多关于如何编写可测试代码的知识。如果你想要的是能够实现最终目标并允许测试的合同,那么它起初可能过于抽象。但是,当你看到代码并且可以说“这里的单身完全破坏依赖注入并使测试变得不可能”时,你就会开始了解哪种模式可以让你的测试生活更轻松。
好吧,如果你不编写测试第一,它不是“测试驱动”,它只是测试。它本身就有好处,如果你已经有了一个代码库,那么即使它不是TDD而只是测试,添加测试肯定是有用的。
首先编写测试是关注代码在编写之前应该做什么。是的,你也做了一个测试,这很好,但有些人可能认为这甚至不是最重要的一点。
我要做的是使用TDD在toy projects like these上训练团队(参见Coding Dojo,Katas)(如果你能让经验丰富的TDD程序员参加这样的研讨会,那就更好了)。当他们看到好处时,他们会将TDD用于实际项目。但同时不要强迫他们,他们没有看到他们不会做对的好处。
如果您在编写代码之前有设计会话或必须生成设计文档,那么您可以添加单元测试作为会话的实际结果。
然后,这可以作为您的代码应如何工作的规范。鼓励在设计会话上进行配对,让人们谈论某些事情应该如何运作以及在特定场景中应该做些什么。什么是边缘情况,为它们提供明确的测试用例,以便每个人都知道如果给出一个null参数,它会做什么。
除此之外,BDD也可能是有意义的
您可以通过显示一个或两个示例来找到一些牵引力,其中TDD导致编写的代码更少 - 因为您只编写了使测试通过所需的代码,金板或参与YAGNI的诱惑更容易抵抗。你不写的代码不需要维护,重构等,所以这是一个“真正的节省”,可以帮助销售TDD的概念。
如果您可以清楚地展示时间,成本,代码和保存的错误的价值,您可能会发现它更容易出售。
开始构建JUnit测试类是开始的方法,对于现有代码,它是唯一的开始方式。根据我的经验,为现有代码创建测试类非常有用。如果管理层认为这会花费太多时间,那么当相应的类被发现包含错误或者需要清理时,您可以建议只编写测试类。
对于维护过程,让团队超越线路的方法是编写JUnit测试以在修复之前重现bug,即
- 报告错误
- 如果需要,创建JUnit测试类
- 添加一个重现该bug的测试
- 修复你的代码
- 运行测试以显示当前代码不会重现该错误
你可以解释一下,通过这种方式“记录”错误可以防止这些错误在以后再次出现。这是团队可以立即体验的好处。
我已经在许多组织中完成了这项工作,我发现启动TDD的最佳方法是设置结对编程。如果你有其他人可以指望知道TDD,那么你们两个可以分开并与其他开发人员配对,实际使用TDD进行一些配对编程。如果没有,我会培训一些能帮助你做到这一点的人,然后再将其提交给团队的其他成员。
单元测试,特别是TDD的主要障碍之一是开发人员不知道如何去做,所以他们看不出它是如何值得花时间的。此外,当你刚开始时,它会慢很多,似乎没有提供好处。只有当你擅长时,它才真正为你提供好处。通过设置成对的编程会话,您可以快速让开发人员快速学习并快速掌握它。此外,当您一起工作时,他们将能够立即从中获益。
这种方法过去曾多次为我工作过。
发现TDD优势的一种有效方法是对某些现有功能进行重大改写,可能是出于性能原因。通过创建一套能够很好地覆盖现有代码的所有功能的测试,您可以放心地重构内容,并确信您的更改是安全的。
请注意,在这种情况下,我正在谈论测试设计或合同 - 测试实现细节的单元测试在这里不合适。但话说再说一遍,TDD无法按定义测试实现,因为它们应该在实现之前编写。
TDD是开发人员可以用来生成更好代码的工具。我碰巧认为编写可测试代码的练习至少和测试本身一样有价值。为测试目的而隔离IUT(被测实施)会产生解耦代码的副作用。
TDD并不适合每个人,并且没有任何魔法会让团队选择这样做。风险在于,不知道什么值得测试的单元测试编写者会编写大量低价值测试,这将成为组织中TDD怀疑论者的炮灰。
我通常使自动验收测试不可协商,但允许开发人员采用适合他们的TDD。我有经验丰富的TDDers培训/指导其余部分并在几个月的时间内通过实例“证明”有用性。
这既是一种社会/文化变革,也是一种技术变革。
代码编写完成后仍然值得编写单元测试。只是有时它往往更难,因为你的代码不是为了测试而设计的,你可能会过于复杂。
我认为将团队纳入TDD的一种良好务实的方法是在过渡期或可能长期提供“在开发期间测试”的替代方法。应该鼓励他们使用看起来很自然的TDD代码段。但是,在代码部分似乎很难接近测试优先或使用由非敏捷A&D流程预先确定的对象时,开发人员可以选择编写一小部分代码,然后编写测试来覆盖代码,并重复此过程。在编写代码之后立即编写单元测试某些代码比完全不编写任何单元测试更好。
在我看来,最好是在“代码优先,测试后”和100%完成的库中获得50%的测试覆盖率,而不是100%的测试覆盖率和50%完成的TDD库。过了一段时间,你的开发人员希望能够为他们编写的所有public
代码编写测试,这对他们来说是有趣的和有教育意义的,所以TDD会潜入他们的开发程序。
我只是在日历上看到这一点:“每一条规则,最大限度地执行,变得荒谬甚至危险。”所以我的建议是不要虔诚。您的团队中的每个成员都必须在测试时感觉“正确”之间取得平衡。通过这种方式,团队中的每个成员都将获得最高效率(而不是说,思考“为什么我必须编写这种标准测试?”)。
所以有些测试总比没有好,代码之后的测试比代码优于之后的测试和测试要好。但每一步都有其自身的优点,你不应该对甚至小步骤不屑一顾。
TDD是关于设计的!因此,如果您使用它,您将确保拥有可测试的代码设计,从而更容易编写测试。如果你在编写代码后编写测试它们仍然很有价值,但恕我直言,你将浪费时间,因为你可能没有可测试的设计。
我可以给你一个建议说服你的团队采用TDD的建议是使用Fearless Change: Patterns for Introducing New Ideas, by Mary Lynn Manns and Linda Rising中描述的一些技术。
如果他们刚接触测试,那么IMO就会开始测试已经编写好的代码并慢慢毕业,先编写测试代码。当有人试图学习TDD和新的单元测试时,我发现很难做一个完整的180并改变我的思维方式在代码之前编写测试,所以我采取的方法是50-50混合;当我确切地知道代码的样子时,我会编写代码,然后编写一个测试来验证它。对于我不完全确定的情况,我将从测试开始,然后向后工作。
还要记住,编写测试来验证代码没有错,而不是编写代码来满足测试。如果您的团队不想使用TDD路线,请不要强行使用它。
编写代码后,我可能成功让团队编写单元测试(可能是检查代码的要求),我的假设是编写单元测试仍然有价值。
毫无疑问,单元测试代码中存在价值(无论何时编写测试),并且我在“完成定义”中包含“代码经过单元测试”。只要他们测试,人们可以使用TDD或不使用TDD。
关于版本控制,我喜欢使用“开发分支”和单元测试策略(即代码编译和构建,所有单元测试都通过)。功能完成后,它们将从开发分支发布到主干。换句话说,主干分支是“完成分支”(主干上没有垃圾!)并且具有可发布的策略(可以在任何时间释放),这是更严格的并且包括比“单元测试”更多的东西。
这是你的团队在开始相信它之前必须有自己的成功。我会为任何关心的人咆哮我的nUnit顿悟:
大约5年前,我在一个项目上发现了nUnit。我们差不多完成了V1.0,我创建了一些测试来试用这个新工具。我们有很多错误(显然!)因为我们是一个新的团队,在一个紧迫的期限,高期望(听起来很熟悉?)等等。无论如何我们得到1.0并开始1.1。我们重新组建了一些团队,并为我分配了两个开发人员。我为他们做了一个小时的演示,告诉他们我们写的所有内容都必须有一个测试用例。在1.1开发周期期间,我们不断地在团队其他成员的后面跑,因为我们编写了更多的代码,单元测试。我们最终工作得更多但是这里是收益 - 当我们最终进入测试时,我们的代码中只有0个错误。我们帮助其他人调试和修复他们的错误。在尸检中,当虫子计数出现时,它引起了所有人的注意。
我并不傻到认为你可以测试你的成功之路,但在单元测试中我是一个真正的信徒。该项目采用了nUnit,由于成功,它很快就传播到公司所有.Net项目。我们V1.1版本的总时间为9个星期,因此绝对不是一夜之间的成功。但从长远来看,它证明了我们的项目和我们为其建立解决方案的公司是成功的。
毫无疑问,测试(首先,甚至是之后)将节省您的培根,并提高您的生产力和信心。我建议采用它!
我处于类似的情况,因为我是一名“noob”开发人员,因为贡献打破了构建,我在团队项目工作时经常感到沮丧。我不知道是否应该责备,甚至在某些情况下,应该责怪谁。但是我更担心的是我和其他开发人员做同样的事情。然后,这种认识促使采用一些TDD策略。我们的团队开始有愚蠢的游戏和规则,就像你在所有测试通过之前都无法回家,或者如果你提交没有测试的东西,那么你必须购买所有人“啤酒/午餐/等”,这使TDD更有趣。
以上是关于TDD与单元测试[已结束]的主要内容,如果未能解决你的问题,请参考以下文章