# 介绍

### **一． TDD是什么？**

阅读前请先看以下文章

[为毛你深陷故障驱动式开发](https://www.jianshu.com/p/3dce62629a14)

[无bug，不生活](https://www.jianshu.com/p/9c19fe71dd9d)

TDD（Test-Driven Development）是敏捷开发中的一项核心实践和技术，也是一种设计方法论，其基本思想是：在明确要开发某个功能后，在开发功能代码之前，先编写测试代码，然后编写功能代码并用测试代码进行验证，如此循环直到完成全部功能的开发。

> TDD 有广义和狭义之分，常说的是狭义的 TDD，也就是 UTDD（Unit Test Driven Development）。广义的 TDD 是 ATDD（Acceptance Test Driven Development），包括 BDD（Behavior Driven Development）和 Consumer-Driven Contracts Development 等，我们现在讨论的TDD 指狭义上的 TDD，也就是「单元测试驱动开发」。

### **二．传统开发模式与TDD开发模式**

**1. 传统开发模式流程:**

**项目代码开发 -> 编写测试用例 –> 运行测试用例 -> 修复代码BUG**

![](https://2056388194-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfwIC9s9ctw6bxuGRce%2F-Lfw_WimeLGQtiJhPPTm%2F-Lfwz0gvWV_HlyP5CSTW%2Fimage.png?alt=media\&token=5429c6d8-7767-433e-9b63-d4e05985d467)

**2. TDD开发模式流程**

**编写测试用例 -> 运行测试用例 –> 编写项目代码 -> 运行测试用例 -> 重构代码**

![](https://2056388194-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfwIC9s9ctw6bxuGRce%2F-Lg0FKS-9b9FYKjs166i%2F-Lg0FNF8yGBuTIaH_YPE%2Fimage.png?alt=media\&token=9c1edb27-4c9a-4890-a672-a1b33174dc2d)

### **三．TDD入门难题**

说到写测试用例，一般的同学都觉得没啥问题，就根据已有的代码，顺着葫芦摸瓜的就把该测试的方法都照着“套”一遍，测试有哪些结果也得顺着项目的代码来。

至于这测试代码能不能测出项目的问题，那是另外的问题，关键是测试代码要Pass，那我的工作才能算完。

但是要在还没项目代码之前写测试用例，那就是等于我要凭空想象那些个抽象又晦涩难懂的功能点，还得要在心中勾勒出它们的轮廓以及细节，这不等于让我自己画个饼来充饥么？问题是我连这饼应该是啥样子都还没个谱，这是何等的悲凉&#x554A;**！**

### **四．TDD的优点与缺点**

#### **优点**

**1. 保证代码质量，鼓励开发人员仅编写满足需求的代码。**

“李雷”同学号称马虎王，经常各种物品丢失，比如女友（对象）丢失；借用物品（引用）丢失；使用“IO自来水”之后不关阀门；去仓库（Database）取货，因为忘记某些物品，不得不频繁往返等等。

“韩梅梅”同学功力深厚，精心打造出了一段瑞士军刀般的代码，耗时5天（其实此功能客户无扩展需求仅要求1天时间完成）。

而在TDD实践中，我们需要注重代码质量，并编写刚好适量的代码。

**2. 保证代码与业务需求的一致性**

一般来讲程序员都愿意把功能完美的体现在代码上，可有时候天不随人意，心里免不得担忧，我这代码能满足业务需求么？但在TDD中，首先是进行测试用例的编写，然后再进行类或者用户界面的开发。由于要先开发测试用例，那么开发人员就必须清楚测试的目的，这样TDD确保了项目的代码与所需的业务是匹配的。

3\. **创建简明有针对性的接口**

一日，“李雷”接到“韩梅梅”发来的为某个功能准备的闯关宝典和核心步骤（类库与接口）。可读了3000遍还是没有能理解，一方面是“韩梅梅”采用了古代文言文与现代拉丁语的混搭来书写核心步骤，另一方面“韩梅梅”的“韩”式1到1000000的命名规则让“李雷”在读了30秒核心步骤后，已经不知道第几条是第几条，。

在TDD实践中，我们要注重创建有意义的、简明的接口，因为这一点在与他人合作中尤其重要。

**4. 与用户沟通，明确需求**

在开发代码的过程中，我们总会有遇到不太明确的需求点，这个时候和需求人员沟通那是必不可少的，了解了功能的输入和输出才能保证完美的完成任务。在沟通的过程中也加深了与客户的信任和默契度，不知不觉中还能提高EQ，一举两得。

**5. 回归测试，确保新的更改不影响现有功能**

在“韩梅梅”同学开发某个功能3个月后，“李雷”接到上级指示，客户要扩展该功能，但是原有功能保持不变。在苦心操劳了之后，“李雷”同学光荣的完成了任务，正准备接受大家赞誉时，“韩梅梅”跳出来向大家诉苦，那就是“李雷”为了做扩展功能把她之前做的功能给弄坏了，当时“李雷”那个心啊，拔凉拔凉的！

TDD的开发中加入了回归测试，这样就确保了之前的功能的正确与完整性，减少不必要的问题。

6\. **提升系统的开放性和扩展性**

一直以来我们做事都要讲先后顺序，软件开发也有着类似的工序。“李雷”和“韩梅梅”被一起“充军”到某紧急功能模块上，并且“李雷”要等“韩梅梅”完成她的功能模块才能开始自己的模块。为了解决这个问题，项目组决定使用某些技术来解除他们的依赖关系，比如使用到IOC以及一些设计模式，让他们能够同时开发，之后再将两人的功能模块组装到一起。

#### 缺点

增加代码量。测试代码是系统代码的两倍或更多，但是同时节省了调试程序及挑错时间。

### **五．TDD开发中需要使用到的技术知识点**：**单元测试、依赖注入框架和模拟对象**

### &#x516D;**．一句话白话**

TDD就是为换一种方式，代码编写前，测试代码先行，一切都是为了提高代码质量，提高代码的可读性，健壮性，可维护性。

### **参考资料**

[试驱动开发实践 - Test-Driven Development](https://www.cnblogs.com/zhq3051/p/4596049.html)
