# 介绍

### **一． 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tdd.shujuwajue.com/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
