程序员有必要掌握 TDD 吗?

你好,我是Weiki,欢迎来到猿java。

你听过或者了解过 TDD 吗? 你知道 TDD 是什么吗?你知道它是如何工作的吗?今天我们就来聊聊 TDD。

曾经在Martin Fowler(马丁·福勒) 的个人博客里看过一篇关于Kent Beck、David 、Martin Fowler 3位大牛关于 Is TDD Dead 的讨论以及David
TDD is dead. Long live testing. 的帖子。

几位作者的部分介绍

Martin Fowler(马丁·福勒),出生于英格兰,后移居美国,像微服务,

DSL(领域设计语),统一建模语言等思想都是出自他,大家有兴趣可以看看他的个人博客:

https://martinfowler.com/,上面有很多优秀的博文,思想值得我们拜读。

Kent Beck:美国人,JUnit单元测试框架作者之一,敏捷开发的开创者之一

David Heinemeier Hansson:丹麦人,Ruby语言创始人

TDD 是什么 ?

TDD 是来自极限编程,百度百科的解释如下:
TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前, 先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法
的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他 开发方法和过程。

这个解释是比较片面的,其实TDD 包含两大部分:ATDD 和 UTDD

ATDD

Acceptance Test Driven Development,验收驱动开发。比如,QA(质量保障)会编写测试用例,然后和PM(产品经理),RD(技术开发)一起评审,这个过程可以帮助RD更好的理解业务需求和验收条件,以至于在后面的代码编写中带着验收目标直到验收测试用例通过。
测试的方式有很多,比如BDD(功能测试),白盒测试,集成测试等等,根据不同的场景采用不同的测试手段,以便达到验收通过。

UTDD

Unit Test Driven Development,单元测试驱动开发,RD先编写单元测试用例,然后再编写实现代码直到单元测试通过。
关于ATDD和UTDD 在Thoughtworks官网,有一张抽象图,大家可以参考下:

img.png

下面整理了一个xmind图

img.png

如何做好 TDD?

在分析TDD方案之前,我们先来解决一个问题:测试驱动开发,整个过程从哪里开始?

答案:测试

那么,测试又从哪里开始呢?
答案:需求。
如果没有需求,测试的目标是什么?因此需求是测试的源头;面对庞大的需求,要如何测试?方法是将需求分解成一个一个可实施测试的小任务。
所以 测试驱动开发要从任务分解开始。

下面摘取了 Thoughtworks 官网的2张图片,来表达TDD的整个过程。
TDD实施-步骤示意图:

img.png

TDD实施-协作示意图:

img.png

个人觉得TDD 可以和 DDD 一样,从战略和战术两个角度来实施。

战略角度

战略角度,更多是一个思想层面的方法论,它可以指导我们以一种更优的方式去实施TDD。

下面先描述一个需求从提出到上线的整个生命周期:

当接到一个新需求时,

  • 首先,PM会有需求评审,评审会阐述业务背景,讲解需求解决的问题以及要达到什么目标;
  • 然后,RD会根据需求评审,做业务分解、上下游沟通、接着做技术详设,技术串讲;
  • 接着,QA会结合需求评审和RD的技术串讲编写测试用例以及用例评审,多方拉齐验收目标和上线时间;
  • 再接着,RD会做架构设计,代码设计以及代码编写,代码测试;QA会做测试相关的工作,比如:用例设计,测试脚本等;
  • 最后,RD开发完成&提测,QA进行测试直到准出,PM进行最后的验收直到代码上线;

整个流程体现了TDD的战略思想,整个生命周期为ATDD和UTDD提供了一定的流程规范。

战术角度

战术角度,更多是从技术层面来阐述。在战略角度我们提出了方法论,针对流程里面的每个步骤要怎么落地,这个就是战术角度。

  • 比如:需求分解,需要按照什么维度分解,是按照领域划分还是按照过程划分,任务分解成多大才算合理。
  • 比如:架构设计,要用什么架构思想,是六边形架构还是洋葱架构。
  • 比如:代码设计,需要用到什么设计模式,适配器模式还是工厂模式。
  • 比如:代码编写,需要用到什么数据结构,算法,怎么让代码更具有复用性。
  • 比如:测试,如何设计测试用例,选用什么测试框架,怎么让测试变得自动化

TDD的实施有一个经典三步曲:红 - 绿 - 重构,不论是ATDD还是UTDD都可以按照这个三步来实施,三部曲示意图如下:

img.png

在很多测试框架中 红代表测试没有通过,绿代表测试通过,而要想让红变成绿就需要经过不断的重构。

因此,我们可以理解:为了写测试,首先“驱动”着我们理解业务,把需求分解成一个个的任务,然后会“驱动”着我们给出一个可测试的设计,而在具体的写代码阶段,又会“驱动”着我们不断改进写出来的代码。把这些内容结合起来看,我们真的是在用测试“驱动”着开发。

有了战略和战术的指导,最主要的就是需要修炼支撑这些策略的能力。实施 TDD 最好需要具备以下能力:

  • 测试前移(左移)的思维能力
  • 业务和技术需求的分析和任务拆分能力
  • 测试用例设计能力
  • 自动化测试开发
  • 能力代码重构
  • 能力持续改进的能力

误区

误区1

在很多程序员的理解中,UTDD就是TDD,TDD就是UTDD,以至于我们把面向业务或测试的ATDD给忽略了,因此,无形中把TDD的范围给缩小了。下面给了一个ATDD和UTDD的对标表

误区2

TDD 就是先写测试后写代码,原因已经在TDD 战术部分中分析过。

TDD真的"死了"吗?

如文章开头 Is TDD Dead?

答案是:NO, 而且目前TDD活的还是不错的,很多公司一直在践行它,只是没有特别去强调它是TDD的范畴。 同时,TDD不是银弹,不可能解决实际工作中的任何问题,我们要做的是不断的学习,比较和总结,根据实际的业务需求去实施,毕竟合适才是最好的。

程序员真的有必要掌握TDD吗?

很有必要,我们不一定要特别强调TDD这个概念,但是TDD根本就是保证程序员的代码质量,而代码质量是程序员的底线
UTDD可以帮助程序员更好,更系统的去写单测;ATDD,可以让程序员更好的了解业务,通过更深度的了解业务来保证代码对业务的健壮性。

参考文献

Thoughtworks官网TDD

Martin Fowler博客

书籍:Java测试驱动开发 (Viktor Farcic著,袁国忠译)

敏捷软件开发(RobertC.Martin 著)

猜你喜欢

转载自blog.csdn.net/m0_54369189/article/details/126157646
TDD