美文网首页
深入单元测试系列之二,TDD和单元测试

深入单元测试系列之二,TDD和单元测试

作者: 杰哥的集思录 | 来源:发表于2021-02-21 22:17 被阅读0次

测试驱动开发(TDD)的全称是Test-Driven Development。上一篇文章中,介绍了Kent Beck,他是极限编程的创始人,测试驱动开发是在极限编程中引入的一种编程实践和技术,是敏捷软件开发的关键实践之一。测试驱动开发是先编写测试案例,然后再实现代码。

Kent和Erich Gamma在1997年10月搭乘同一趟航班飞往美国亚特兰,参加一年一度的OOPSLA(Object Oriented Programming Systems Languages &Applications)会议。OOPSLA会议是美国计算机协会(ACM)举办的一个年度性会议,第一届是1986年在美国波特兰市举办,最后一期是2010年,后来成为了SPLASH (Systems, Programming, Languages, and Applications: Software for Humanity)的一部分,是一个IT行业牛人云集的会议,会议的主题主要是编程界的前沿技术,具有一定的学术性,比如1997年有一个关于Java(Type Parameterization)泛型的话题,直到2004年的JDK5发布,才正式的支持泛型。

Kent和Erich还是是Eclipse的主要架构设计者,Erich 2011年加入微软,负责Visual Studio Code的开发。Erich最著名的书是《设计模式》,就是我们通常说的23种经典设计模式的作者之一。在飞机上,两个人一拍即合,完成了最初的JUnit版本,是仿照SUnit的Java版本,SUnit是Smalltalk编程语言的测试框架,Junit框架至今已经进化到第五代了,生态圈也非常的完整。

Kent 2011年加入Facebook,担任软件技术教练,负责公司工程师文化的落地和推广,帮助新员工掌握并使用相关的技能。通过敏捷和自动化测试的实施,Facebook可以做到每周甚至每日发布,而且大多数团队没有专职的QA人员。Kent 2019年加入了一家创业型SaaS软件公司Gusto担任Fellow,做着赋能的事情,该公司是人力资源领域的SaaS独角兽,员工1400人,估值约38亿美金。

近些年,有人在TDD 的基础上提出了ATDD(Acceptance Test Driven Development)的概念,包括 BDD(Behavior Driven Development)和 Consumer-Driven Contracts Development 等编程实践和技术,把TDD分为狭义的和广义的,狭义的 TDD是指UTDD(Unit Test Driven Development),而广义的 TDD 是指 ATDD。本文中所指的TDD是指的UTDD,即单元测试驱动开发。

测试驱动有三层含义:
第一层是驱动设计,测试代码相当于是实现代码的客户端,编写测试案例的时候,会迫使开发人员去思考,代码的接口和方法应该如何设计,如何组织代码,如何被客户端调用等;当然这里的驱动设计是值得商榷的,设计形式是多种的,比如UML辅助,也可以采用领域驱动设计(DDD)的方法。
第二层是驱动代码质量,测试案例来源需求,单元测试通过,就可以证明在测试案例覆盖的范围,代码是经过测试的,从而做到测试和BUG修复的循环变得最小,快速获得反馈提升效率,同时代码的质量也会有保障,未来改动代码的时候,运行单元测试,可以及时发现问题,起到防止代码被改坏的作用;
第三层是驱动重构和改进设计,因为有单元测试的保障,开发人员在重构代码之后就不用担心改出问题。

TDD的编码步骤

image

TDD 的基本流程是:红,绿,重构。

  • 根据需求编写一个测试用例
  • 红:运行测试,失败
  • 实现代码刚好能让测试通过
  • 绿:运行测试,成功,失败进入上一步
  • 重构:识别坏味道,用重构手法修改代码
  • 绿:运行测试,成功,失败回到上一步

是否采用了TDD的开发方式就不用Debug了呢?

答案是否定的,开发过程中可能遇到测试失败,但是也无法一下看出代码问题的情况,还是需要使用Debug模式调试代码,查看运行是的变量和代码执行路径。

对于TDD,也有很多常见的观点:

  • 业务需求变化太快,测试代码改来改去浪费时间;
  • 开发时间紧,项目发布都是倒排的计划,根本没时间写TDD代码;
  • 不知道怎么写单元测试,Debug就很好用;
  • 代码从来不进行重构;
  • 使用Mock和Stub技术,UT没有办法测试集成后的功能,业务价值不大;

对于TDD一直存在争议,牛人也是褒贬不一,Kent Beck、Martin Fowler、David Heinemeier Hansson(RoR之父)在2014年有过一场关于TDD的讨论,主题是“TDD已经死了吗?”,有兴趣的可以听一下对话。Is TDD Dead
David他之后又写了“ TDD 已死 - 测试永生”和“测试引起的设计伤害”这两篇文章来对这一主题进行了扩展。

我个人的观点就是,既然测试很重要,那测试是必须的,至于是先测试还是后测试,在开发过程中一定交织在一起的,不用过于纠结是不是TDD。以下是几个实践的建议:
1、不写单元测试,不允许提交代码
2、提交代码前需要本地运行单元测试确保通过
3、持续集成平台需要持续运行单元测试
4、不过度追求100%测试覆盖率

我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。
我们的探寻还尚未结束,TDD 只是我们在这一历程中所寻找到的其中一种,还存在其他方式供我们去继续寻找。

以下内容是经典的TDD的练习题目,FizzBuzz游戏,大家感兴趣可以练习并实践一下,参考视频。

为什么别人写代码那么快?这篇文章是熊节(重构一书译者)举办的程序员练功房培训班里面的作业视频,最快的1分15秒完成了编程,大部分能够在5-10分钟内完成编程。

我自己录制的视频,采用了传统的编码方式,用时6分23秒,差距还是有的。
测试驱动开发示例

想象一下你上小学五年级,在课程结束前的五分钟,你的数学老师说要带着大家玩一个小游戏。他将依次指着每个学生,并要求他们从一开始依次报数。第⼀个被指着的学⽣说“1”,第⼆个被指着的学⽣说“2”,如果数字可被三整除,则不能说数字,要说“Fizz”,如果数字被五可整除,则说“Buzz”。
游戏开始了,⽼师的⼿指向⼀个个同学,他们开⼼地喊着:“1!”,“2!”,“Fizz!”,“4!”,“Buzz!”……终于,⽼师指向了你,时间仿佛静⽌,你的嘴发⼲,你的掌⼼在出汗,你仔细计算,然后终于喊出“Fizz!”。运⽓不错,你躲过了⼀劫,游戏继续进⾏。
为了避免在⾃⼰这⼉尴尬,我们想了⼀个作弊的法⼦:最好能提前把整个列表打印出来,这样就知道到我这⼉的时候该说什么了。全班有33个同学,游戏可能会玩2到3轮。

任务:写⼀个程序,打印出从1到100的数字,将其中3的倍数替换成“Fizz”,5的倍数替换成“Buzz”。既能被3整除、⼜能被5整除的数则替换成FizzBuzz。

样本输出:
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
...

第二阶段,新需求:

  • 如果⼀个数能被3整除,或者包含数字3,那么这个数就是“Fizz”
  • 如果⼀个数能被5整除,或者包含数字5,那么这个数就是“Buzz”

参考:

相关文章

  • 深入单元测试系列之一软件测试的历史

    这是单元测试系列文章第一篇,完整的系列内容: 深入单元测试系列之一,软件测试的历史深入单元测试系列之二,TDD和单...

  • 深入单元测试系列之二,TDD和单元测试

    测试驱动开发(TDD)的全称是Test-Driven Development。上一篇文章中,介绍了Kent Bec...

  • 《徐昊-TDD项目实战70讲》学习笔记 -- Day 7

    07|TDD中的测试(3):集成测试还是单元测试? 集成测试还是单元测试? TDD 中的单元测试 在 TDD 的语...

  • TDD跟单元测试的关系如何处理?

    TDD和单元测试不是一个维度的概念。TDD是一种软件开发方法,单元测试是软件开发中的一种产物。简单区分就是:TDD...

  • 关于Vue单元测试的一些总结

    最近Vue项目要求用到单元测试,就这段时间用到的一些单元测试知识做一下总结。 TDD和BDD的概念 1.TDD(T...

  • NodeJs单元测试

    本博客简要介绍NodeJs如何进行单元测试 单元测试类型 TDD:测试驱动开发TDD的原理是在开发功能代码之前,先...

  • iOS单元测试及TDD开发

    单元测试 什么是单元测试 本文中Demo:在这里[https://github.com/shcamaker/TDD...

  • 代码整洁之道 9、10、11

    单元测试 9.1 TDD三定律 在编写不能通过的单元测试前,不可编写生产代码 只可编写刚好无法通过的单元测试,不能...

  • Robolectric

    开始单元测试之前还是要先了解TDD 中文版:TDD 已死?让我们再聊聊 TDD 英文版:Introduction ...

  • 单元测试

    内容 单元测试 参考文章: [iOS单元测试系列]单元测试框架选型 iOS单元测试:Specta + Expect...

网友评论

      本文标题:深入单元测试系列之二,TDD和单元测试

      本文链接:https://www.haomeiwen.com/subject/eijcfltx.html