TDD(测试驱动开发)死了吗?

本文深入探讨测试驱动开发(TDD)的理念与实践,讲解其基本流程,并通过案例展示如何编写测试用例并逐步完善功能代码,强调TDD对于提升代码质量和重构的信心的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  01、前言

  很早之前,曾在网络上见到过 TDD 这 3 个大写的英文字母,它是 Test Driven Development 这三个单词的缩写,也就是“测试驱动开发”的意思——听起来很不错的一种理念。

  其理念主要是确保两件事:

  确保所有的需求都能被照顾到。

  在代码不断增加和重构的过程中,可以检查所有的功能是否正确。

  但后来很长一段时间里,都没再听过 TDD 的消息。有人说,TDD 已经死了,给出的意见如下:

  1)通常来说,开发人员不应该在没有失败的测试用例下编写代码——这似乎是合理的,但是它可能导致过度测试。例如,为了保证一行生产代码的正确性,你不由得写了 4 行测试代码,这意味着一旦这一行生产代码需要修改,你也得修改那 4 行测试代码。

  2)为了遵循 TDD 而写的代码,容易进入一个误区:代码是为了满足测试用的,而忽略了实际需求。

  02、TDD 到底是什么?

  不管 TDD 到底死了没有,先让我们来回顾一下 TDD 到底是什么。

  TDD 的基本思想就是在开发功能代码之前,先编写测试代码。也就是说在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完成全部功能的开发。

  TDD 的基本过程可以拆解为以下 6 个步骤:

  1) 分析需求,把需求拆分为具体的任务。

  2) 从任务列表中取出一个任务,并对其编写测试用例。

  3) 由于没有实际的功能代码,测试代码不大可能会通过(红)。

  4) 编写对应的功能代码,尽快让测试代码通过(绿)。

  5) 对代码进行重构,并保证测试通过(重构)。

  6) 重复以上步骤。

  可以用下图来表示上述过程。

在这里插入图片描述

 

  03、TDD 的实践过程

  通常情况下,我们都习惯在需求分析完成之后,尽快地投入功能代码的编写工作中,之后再去调用和测试。

  而 TDD 则不同,它假设我们已经有了一个“测试用户”了,它是功能代码的第一个使用者,尽管功能代码还不太完善。

  当我们站在“测试用户”的角度去写测试代码的时候,我们要考虑的是,这个“测试用户”该如何使用功能代码呢?是通过一个类直接调用方法呢(静态方法),还是构建类的实例去调用方法呢(实例方法)?这个方法如何传参呢?方法如何命名呢?方法有返回值吗?

  有了测试代码后,我们开始编写功能代码,并且要以最快地速度让测试由“红”变为“绿”,可能此时的功能代码很不优雅,不过没关系。

  当测试通过以后,我们就可以放心大胆的对功能代码进行“重构”了——优化原来比较丑陋、臃肿、性能偏差的代码。

  接下来,假设我们接到了一个开发需求:

  汪汪队要到小镇冒险岛进行表演,门票为 99 元,冒险岛上唯一的一个程序员王二需要开发一款可以计算门票收入的小程序。

  按照 TDD 的流程,王二需要先使用 Junit 编写一个简单的测试用例,测试预期是:销售一张门票的收入是 99 元。

  

 

  为了便于编译能够顺利通过,王二需要一个简单的 Ticket 类:

  

 

  测试用例运行结果如下图所示,红色表示测试没有通过:预期结果是 99,实际结果是 0。

  

在这里插入图片描述

 

  那接下来,王二需要快速让测试通过,Ticket.sale() 方法修改后的结果如下:

  

 

  再运行一下测试用例,结果如下图所示,绿色表示测试通过了:预期结果是 99,实际结果是 99。

在这里插入图片描述

 

  绿了,绿了,测试通过了,到了该重构功能代码的时候了。99 元是个魔法数字,至少应该声明成常量,对吧?

  

 

  重构完后再运行一下测试用例,确保测试通过的情况下,再增加几个测试用例,比如说门票销量为负数、零甚至一千的情况。

  

 

  销量为负数的时候,王二希望功能代码能够抛出异常;销量为零的时候,功能代码的计算结果应该为零;销量为一千的时候,计算结果应该为 99000。

  重新运行一下测试用例,结果如下图所示:

  

在这里插入图片描述

 

  有两个测试用例没有通过,那么王二需要继续修改功能代码,调整如下:

  

 

  再运行一下测试用例,发现都通过了。又到了重构的时候了,销量为零、或者大于等于一的时候,代码可以合并,于是重构结果如下:

  

 

  重构结束后,再运行测试用例,确保重构后的代码依然可用。

  04、最后

  从上面的实践过程可以得出如下结论:

  TDD 想要做的就是让我们对自己的代码充满信心,因为我们可以通过测试代码来判断这段代码是否正确无误。

  也就是说,TDD 流程比较关键的一环在于如何写出有效的测试代码,这里有 4 个原则可以参考:

  1)测试过程应该尽量模拟正常使用的过程。

  2)应该尽量做到分支覆盖。

  3)测试数据应该尽量包括真实数据,以及边界数据。

  4)测试语句和测试数据应该尽量简单,容易理解。

  注意,这 4 个原则不仅适用于 TDD,同样适用于任何流程下的单元测试。

  最后,我想说的是,不管 TDD 有没有死,TDD 都不是银弹,不可能适合所有的场景,但这不应该成为我们拒绝它的理由。

  

资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值