从零开始学习Java中的TDD:测试如何改变代码并拯救你的神经

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么TDD不是关于“编写测试”,而是关于“换个方式思考”

\n\n

想象一下你在盖房子。你有图纸、材料和施工队。但你开始砌砖之前没有检查地基。一个月后,你发现墙壁出现了裂缝。熟悉吗?在编程中,这被称为“以后修复”。而“以后”通常发生在部署前的凌晨3点。

\n\n

测试驱动开发(TDD — Test-Driven Development)是一种彻底颠覆流程的技术。你不是先写代码,再写测试。而是先写测试——然后只写能让测试通过的代码。听起来很疯狂?实际上,它能节省时间、神经,并使代码比山间的清晨空气更干净。

\n\n

在本文中,我们将通过具体示例解析Java中的TDD。没有废话——只有代码、红-绿-重构循环和真实场景。我们开始吧。

\n\n

什么是TDD以及红-绿-重构循环如何工作

\n\n

TDD基于三个简单的步骤,循环重复:

\n\n
    \n
  • 红 — 编写一个不通过的测试(它应该失败)。
  • \n
  • 绿 — 编写最少的代码以使测试通过。
  • \n
  • 重构 — 改进代码而不改变其行为。测试在此期间保持绿色。
  • \n
\n\n

这似乎会减慢开发速度。实际上,它加快了速度。你不再猜测“这能工作吗?”。你知道:它能工作,因为测试是绿色的。

\n\n

TDD的主要原则

\n
    \n
  • 没有测试就不要写一行生产代码。
  • \n
  • 测试应该尽可能简单,并且只测试一种行为。
  • \n
  • 代码只写到足以让测试通过。没有“以防万一,我们再添加这个”的情况。
  • \n
\n\n

现在让我们转向Java和JUnit 5——最流行的单元测试框架。

\n\n

项目设置:Maven、JUnit 5和结构

\n\n

对于示例,我们将使用Maven。在pom.xml中添加依赖:

\n\n
<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter-api</artifactId>\n    <version>5.10.0</version>\n    <scope>test</scope>\n</dependency>
\n\n

Maven的标准文件夹结构:

\n
src/\n  main/java/com/example/\n  test/java/com/example/
\n\n

所有测试类放在src/test/java中。测试类的名称通常与被测试类的名称一致,并加上Test后缀。例如,Calculator → CalculatorTest。

\n\n

第一个TDD循环:从零开始编写计算器

\n\n

任务:创建一个方法add(int a, int b),返回两个数的和。按照TDD,我们不是从类开始,而是从测试开始。

\n\n

步骤1:红 — 编写一个会失败的测试

\n\n
import org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.*;\n\npublic class CalculatorTest {\n\n    @Test\n    void shouldAddTwoNumbers() {\n        Calculator calc = new Calculator();\n        int result = calc.add(2, 3);\n        assertEquals(5, result);\n    }\n}
\n\n

尝试运行——编译器报错:类Calculator不存在。很好,红灯亮起。

\n\n

步骤2:绿 — 编写最少的代码

\n\n

创建类Calculator,其中包含一个简单返回和的方法:

\n\n
public class Calculator {\n    public int add(int a, int b) {\n        return a + b;\n    }\n}
\n\n

运行测试——绿色。最小可行的实现已经生效。

\n\n

步骤3:重构

\n\n

在这个阶段,代码已经很简单,没有什么需要重构的。但假设我们想重命名方法或添加溢出检查。我们这样做,测试仍然通过。如果有什么东西坏了——测试会失败并立即指出问题。

\n\n

复杂

博客

书籍推荐