# 教程：测试驱动开发

> For the complete documentation index, see [llms.txt](https://www.jetbrains.com.cn/help/idea/llms.txt).

无论您喜欢在编写生产代码之前编写测试，还是喜欢事后再创建测试， IntelliJ IDEA 都能轻松创建并运行单元测试。 在本教程中，您将学习如何使用 IntelliJ IDEA 优先编写测试（ [测试驱动开发或 TDD](http://martinfowler.com/bliki/TestDrivenDevelopment.html)）。 请参阅 [Kotlin 文档](https://kotlinlang.org/docs/jvm-test-using-junit.html)了解详情。

## 创建项目

Procedure: 创建一个新的项目

1. 打开   新建项目  向导：

* 如果位于主屏幕，请选择 `![加号](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.general.add.svg) 新建 | ![文件夹图标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.nodes.folder.svg) 项目……` 。

* 如果已打开另一个项目，请转到 `文件 | 新建 | 项目` 。

2. 在向导左侧，选择 ![Java 徽标](https://resources.jetbrains.com.cn/help/img/idea/2026.3/intellij.platform.icons.expui.fileTypes.java.svg)   Java  。

3. 请为新项目命名，例如：  `MoodAnalyser` ，并在必要时更改其位置。

4. 选择   Gradle   作为构建工具，并将   Groovy   作为 DSL。

5. 从    JDK    列表中选择您想在项目中使用的 [JDK](sdk.html#jdk)。

* 如果已在计算机上安装 JDK，但未在 IDE 中定义，请选择 ![](https://resources.jetbrains.com.cn/help/img/idea/2026.3/app.expui.nodes.jdk.png) 从磁盘添加 JDK… 并指定 JDK 主目录的路径。​

* 如果您的计算机上没有必要的 JDK，请选择 ![](https://resources.jetbrains.com.cn/help/img/idea/2026.3/app-client.expui.general.download.svg) 下载 JDK 。

6. 点击   创建  。

IntelliJ IDEA 创建了一个具有预配置结构和基本库的项目。  `build.gradle`  文件中将添加 JUnit 5 作为依赖项。

Procedure: 创建新包

1. 在   项目   工具窗口中，右键点击  `main | java`  文件夹，并选择  `新建 | 包` 。

2. 将新包命名为  `com.example.demo` ，然后按下 `Enter` (Windows), `⏎` (macOS), `⏎` (IntelliJ IDEA Classic (macOS)), `⏎` (macOS System Shortcuts), `Enter` (XWin), `Enter` (GNOME), `Enter` (KDE), `Enter` (Emacs), `Enter` (Sublime Text), `⏎` (Sublime Text (macOS)), `Enter` (Visual Studio), `⏎` (Visual Studio (macOS)), `Enter` (NetBeans), `Enter` (Eclipse), `⏎` (Eclipse (macOS))。

## 编写测试主体

Procedure: 创建您的第一个测试

考虑到我们先编写测试，而不一定需要代码已对我们可用，我们将在项目面板中创建第一个测试，并将其放置在一个包中。

1. 右键点击测试根文件夹 ![](https://resources.jetbrains.com.cn/help/img/idea/2026.3/app-client.expui.nodes.testRoot.svg)并选择  `新建 | Java 类` 。

在打开的弹出窗口中，为新包和测试类命名：  `com.example.demo.MoodAnalyserTest` 。

![测试类已创建](https://resources.jetbrains.com.cn/help/img/idea/2026.3/ij_tdd_create_test.png)

2. 将插入符号置于类的大括号内，按下 `Alt+Insert` (Windows), `⌘ N` (macOS), `⌃ N` (IntelliJ IDEA Classic (macOS)), `⌘ N` (macOS System Shortcuts), `Alt+Insert` (XWin), `Alt+Insert` (GNOME), `Alt+Insert` (KDE), `Alt+Insert` (Emacs), `Alt+Insert` (Sublime Text), `⌘ N` (Sublime Text (macOS)), `Alt+Insert` (Visual Studio), `⌘ ⌃ N` (Visual Studio (macOS)), `Alt+Insert` (NetBeans), `Alt+Insert` (Eclipse), `⌘ N` (Eclipse (macOS))。

3. 请从菜单中选择   测试方法   来根据默认模板创建测试方法。

将方法命名为  `testMoodAnalysis` ，按 `Enter` (Windows), `⏎` (macOS), `⏎` (IntelliJ IDEA Classic (macOS)), `⏎` (macOS System Shortcuts), `Enter` (XWin), `Enter` (GNOME), `Enter` (KDE), `Enter` (Emacs), `Enter` (Sublime Text), `⏎` (Sublime Text (macOS)), `Enter` (Visual Studio), `⏎` (Visual Studio (macOS)), `Enter` (NetBeans), `Enter` (Eclipse), `⏎` (Eclipse (macOS))，文本光标将停留在方法体内。

![创建您的第一个测试](https://resources.jetbrains.com.cn/help/img/idea/2026.3/generate-method.png)

您可以更改 [默认测试方法模板](using-file-and-code-templates.html)——例如，若要将方法名称的开头从  `test` 更改为  `should` 。

Procedure: 从测试中新建类

虽然为不存在的类和方法编写测试代码看起来有悖常理，但 IntelliJ IDEA 可以使这一过程变得简单，同时让编译器满意。 IntelliJ IDEA 可以为您创建类和方法，如果它们还不存在的话。

1. 键入  `new MoodAnalyser` ，按下 `Alt+Enter` (Windows), `⌥ ⏎` (macOS), `⌥ ⏎` (IntelliJ IDEA Classic (macOS)), `⌥ ⏎` (macOS System Shortcuts), `Alt+Enter` (XWin), `Alt+Enter` (GNOME), `Alt+Enter` (KDE), `Alt+Enter` (Emacs), `Alt+Enter` (Sublime Text), `⌥ ⏎` (Sublime Text (macOS)), `Alt+Enter` (Visual Studio), `⌥ ⏎` (Visual Studio (macOS)), `Alt+Enter` (NetBeans), `Ctrl+1` (Eclipse), `⌘ 1` (Eclipse (macOS))，然后选择   创建类 'MoodAnalyser'  。

![从测试中创建新类](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-create-class.png)

2. 在打开的对话框中，选择  `com.example.demo`  包位于  `main | java`  文件夹中，然后点击   OK  。

![选择目标包](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-class-in-target-package.png)

Procedure: 创建变量

和往常一样，您可以使用 IntelliJ IDEA 的 [重构工具](refactoring-source-code.html)创建变量来存储结果，同时如果正确的库在类路径中，IntelliJ IDEA 将为您导入最合适的类。

1. 切换回测试类，将光标放置在  `new MoodAnalyser`  之后，输入  `()`  并按 `Ctrl+Alt+V` (Windows), `⌘ ⌥ V` (macOS), `⌘ ⌥ V` (IntelliJ IDEA Classic (macOS)), `⌘ ⌥ V` (macOS System Shortcuts), `Ctrl+Alt+V` (XWin), `Ctrl+Alt+V` (GNOME), `Alt+Shift+V` (KDE), `Ctrl+Alt+V` (Emacs), `Ctrl+Alt+V` (Sublime Text), `Ctrl+Alt+V` (Sublime Text (macOS)), `Ctrl+R, V` (Visual Studio), `⌘ R, V` (Visual Studio (macOS)), `Alt+Shift+V` (NetBeans), `Alt+Shift+L` (Eclipse), `⌘ ⌥ L` (Eclipse (macOS)) 以调用 [提取/引入变量](extract-variable.html) 重构。

2. 将新变量命名为  `moodAnalyser` 。

![Tdd extract variable](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-extract-variable.png)

> **Tip:**
> 将文本光标放置在源代码中的测试类或测试对象处，然后按 `Ctrl+Shift+T` (Windows), `⌘ ⇧ T` (macOS), `⌘ ⇧ T` (IntelliJ IDEA Classic (macOS)), `⌃ ⇧ T` (macOS System Shortcuts), `Ctrl+Shift+T` (XWin), `Ctrl+Shift+T` (GNOME), `Ctrl+Shift+T` (KDE), `Ctrl+Shift+T` (Emacs), `Ctrl+Shift+T` (Sublime Text), `Ctrl+Shift+T` (Sublime Text (macOS)), `Ctrl+Shift+T` (Visual Studio), `Ctrl+Shift+T` (Visual Studio (macOS)), `Ctrl+Shift+T` (NetBeans), `Ctrl+Shift+T` (Eclipse), `Ctrl+Shift+T` (Eclipse (macOS)) 以便在它们之间快速导航。 或者，使用 [分屏模式](using-code-editor.html#split_screen)同时查看两个文件。

Procedure: 完成测试主体

继续编写测试主体，包括您需要但不存在的方法名称。

1. 在测试类中，输入以下语句：

```JAVA
moodAnalyser.analyseMood("This is a sad message");
```

`analyseMood`  将被标记为未解析的引用。

2. 请将文本光标放在  `analyseMood` ，按 `Alt+Enter` (Windows), `⌥ ⏎` (macOS), `⌥ ⏎` (IntelliJ IDEA Classic (macOS)), `⌥ ⏎` (macOS System Shortcuts), `Alt+Enter` (XWin), `Alt+Enter` (GNOME), `Alt+Enter` (KDE), `Alt+Enter` (Emacs), `Alt+Enter` (Sublime Text), `⌥ ⏎` (Sublime Text (macOS)), `Alt+Enter` (Visual Studio), `⌥ ⏎` (Visual Studio (macOS)), `Alt+Enter` (NetBeans), `Ctrl+1` (Eclipse), `⌘ 1` (Eclipse (macOS))，然后点击   在 'MoodAnalyser' 中创建方法 'analyseMood'  。

![Ij tdd create method](https://resources.jetbrains.com.cn/help/img/idea/2026.3/ij-tdd-create-method.png)

3. 请确保  `MoodAnalyser`  类如下所示：

```JAVA
public class MoodAnalyser {
    public String analyseMood(String message) {
        return null;
    }
}

```

![编写测试主体](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-write-test-body.png)

4. 在测试类中，将文本光标置于  `analyseMood` ，按 `Ctrl+Alt+V` (Windows), `⌘ ⌥ V` (macOS), `⌘ ⌥ V` (IntelliJ IDEA Classic (macOS)), `⌘ ⌥ V` (macOS System Shortcuts), `Ctrl+Alt+V` (XWin), `Ctrl+Alt+V` (GNOME), `Alt+Shift+V` (KDE), `Ctrl+Alt+V` (Emacs), `Ctrl+Alt+V` (Sublime Text), `Ctrl+Alt+V` (Sublime Text (macOS)), `Ctrl+R, V` (Visual Studio), `⌘ R, V` (Visual Studio (macOS)), `Alt+Shift+V` (NetBeans), `Alt+Shift+L` (Eclipse), `⌘ ⌥ L` (Eclipse (macOS))，并输入  `mood` 。

![引入变量 'mood'](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-introduce-variable-mood.png)

Procedure: 添加一个断言语句

1. 打开  `build.gradle`  文件，添加以下依赖项并点击 ![同步 Gradle 更改](https://resources.jetbrains.com.cn/help/img/idea/2026.3/gradle.icons.expui.gradleLoadChanges.svg) 以导入更改：

```GENERIC
dependencies {
    testImplementation(
            'org.hamcrest:hamcrest-library:2.2'
    )
}

```

2. 在  `MoodAnalyserTest`  中，添加以下语句：

```JAVA
assertThat(mood, CoreMatchers.is("SAD"));

```

按 `Alt+Enter` (Windows), `⌥ ⏎` (macOS), `⌥ ⏎` (IntelliJ IDEA Classic (macOS)), `⌥ ⏎` (macOS System Shortcuts), `Alt+Enter` (XWin), `Alt+Enter` (GNOME), `Alt+Enter` (KDE), `Alt+Enter` (Emacs), `Alt+Enter` (Sublime Text), `⌥ ⏎` (Sublime Text (macOS)), `Alt+Enter` (Visual Studio), `⌥ ⏎` (Visual Studio (macOS)), `Alt+Enter` (NetBeans), `Ctrl+1` (Eclipse), `⌘ 1` (Eclipse (macOS)) 导入缺失的方法和类。

### 代码

至此，您的测试类和生成类应如下所示：

MoodAnalyser:

```JAVA
package com.example.demo;

public class MoodAnalyser {
    public String analyseMood(String message) {
        return null;
    }
}

```

MoodAnalyserTest:

```JAVA
package com.example.demo;

import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;


public class MoodAnalyserTest {
    @Test
    void testMoodAnalysis() {
        MoodAnalyser moodAnalyser = new MoodAnalyser();
        String mood = moodAnalyser.analyseMood("This is a sad message");
        assertThat(mood, CoreMatchers.is("SAD"));
    }
}

```

## 运行测试

遵循 TDD 方法时，通常会经历一个 [红—绿—重构](http://martinfowler.com/articles/workflowsOfRefactoring/#tdd) 循环。 您将运行一次测试，看到其失败（变为红色），实现最简单的代码以使测试通过（变为绿色），然后重构代码，使您的测试保持绿色，且代码足够干净。

此循环的第一步是运行测试并看到其失败。

鉴于我们已使用 IntelliJ IDEA 的功能为正在测试的方法创建了最简单的空实现，我们并不指望测试会通过。

Procedure:

* 在测试中，按下 `Ctrl+Shift+F10` (Windows), `⌃ ⇧ R` (macOS), `⌃ ⇧ F10` (IntelliJ IDEA Classic (macOS)), `⌃ ⇧ R` (macOS System Shortcuts), `Ctrl+Shift+F10` (XWin), `Ctrl+Shift+F10` (GNOME), `Ctrl+Shift+F10` (KDE), `Ctrl+Shift+F10` (Emacs), `Ctrl+Shift+F10` (Sublime Text), `Ctrl+Shift+F10` (Sublime Text (macOS)), `Ctrl+Alt+F5` (Visual Studio), `⌃ ⌥ F5` (Visual Studio (macOS)), `Alt+Shift+F6` (NetBeans), `Ctrl+Shift+F10` (Eclipse), `⌃ ⇧ R` (Eclipse (macOS)) 以运行此单个测试。

结果将显示在 [运行工具窗口](viewing-and-exploring-test-results.html) 中。 测试名称旁将有一个图标——红色表示异常，黄色表示断言失败。 对于任意一种失败，还会显示说明出错原因的消息。

![运行测试](https://resources.jetbrains.com.cn/help/img/idea/2026.3/ij_tdd_run_failing_tests.png)

## 实现代码

下一步是让测试通过，这意味着实现最简单可行的内容。 在 TDD 中，最简单可行的内容往往可能是将期望值硬编码。 稍后我们将看到，如何通过迭代此过程来得到更贴近实际的生产代码。

Procedure: 修复测试

1. 在  `MoodAnalyser`  中，用  `null`  替换  `SAD`  返回值：  `return "SAD";` 。

2. 重新运行测试，使用 `Shift+F10` (Windows), `⌃ R` (macOS), `⇧ F10` (IntelliJ IDEA Classic (macOS)), `⌥ ⇧ R` (macOS System Shortcuts), `Shift+F10` (XWin), `Shift+F10` (GNOME), `Shift+F10` (KDE), `Shift+F10` (Emacs), `Shift+F10` (Sublime Text), `Shift+F10` (Sublime Text (macOS)), `Ctrl+F5` (Visual Studio), `⌃ F5` (Visual Studio (macOS)), `F6` (NetBeans), `Alt+Shift+X` (Eclipse), `⌘ ⇧ F11` (Eclipse (macOS)) 重新运行上次测试。

请查看测试通过情况——测试方法旁边的图标应变为绿色。

![重新运行测试](https://resources.jetbrains.com.cn/help/img/idea/2026.3/rerun-test.png)

## 迭代

开发代码是一个迭代过程。 在遵循 TDD 风格的方法时，这一点更是如此。 为了推动更复杂的行为，我们为其他情况添加测试。

Procedure: 添加第二个测试用例

1. 在您的测试类中，再次使用 `Alt+Insert` (Windows), `⌘ N` (macOS), `⌃ N` (IntelliJ IDEA Classic (macOS)), `⌘ N` (macOS System Shortcuts), `Alt+Insert` (XWin), `Alt+Insert` (GNOME), `Alt+Insert` (KDE), `Alt+Insert` (Emacs), `Alt+Insert` (Sublime Text), `⌘ N` (Sublime Text (macOS)), `Alt+Insert` (Visual Studio), `⌘ ⌃ N` (Visual Studio (macOS)), `Alt+Insert` (NetBeans), `Alt+Insert` (Eclipse), `⌘ N` (Eclipse (macOS)) 创建一个新的测试方法。 请命名为  `HappyMoods` 。

2. 将以下代码添加到您的类中。

```JAVA
@Test
void HappyMoods() {
    MoodAnalyser moodAnalyser = new MoodAnalyser();
    String mood = moodAnalyser.analyseMood("This is a happy message");
    assertThat(mood, CoreMatchers.is("HAPPY"));
}

```

![添加第二个测试](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-second-test-method.png)

3. 通过按 `Alt+Shift+R` (Windows), `⌘ ⌃ R` (macOS), `⌘ ⌃ R` (IntelliJ IDEA Classic (macOS)), `⌘ ⌃ R` (macOS System Shortcuts), `Alt+Shift+R` (XWin), `Alt+Shift+R` (GNOME), `Alt+Shift+R` (KDE), `Alt+Shift+R` (Emacs), `Alt+Shift+R` (Sublime Text), `⌘ ⌃ R` (Sublime Text (macOS)), `Alt+Shift+R` (Visual Studio), `Alt+Shift+R` (Visual Studio (macOS)), `Alt+Shift+R` (NetBeans), `Alt+Shift+G` (Eclipse), `⌘ ⌃ R` (Eclipse (macOS)) 运行此第二个测试用例，您将看到它失败。

![添加第二个测试](https://resources.jetbrains.com.cn/help/img/idea/2026.3/tdd-run-tests-happy.png)

Procedure: 修复第二个测试

1. 更改正在测试的方法中的代码以使此测试通过：

```JAVA
package com.example.demo;

public class MoodAnalyser {
    public String analyseMood(String message) {
        if (message.contains(("sad"))) {
            return "SAD";
        } else {
            return "HAPPY";
        }
    }
}

```

2. 通过按下 `Ctrl+Shift+F10` (Windows), `⌃ ⇧ R` (macOS), `⌃ ⇧ F10` (IntelliJ IDEA Classic (macOS)), `⌃ ⇧ R` (macOS System Shortcuts), `Ctrl+Shift+F10` (XWin), `Ctrl+Shift+F10` (GNOME), `Ctrl+Shift+F10` (KDE), `Ctrl+Shift+F10` (Emacs), `Ctrl+Shift+F10` (Sublime Text), `Ctrl+Shift+F10` (Sublime Text (macOS)), `Ctrl+Alt+F5` (Visual Studio), `⌃ ⌥ F5` (Visual Studio (macOS)), `Alt+Shift+F6` (NetBeans), `Ctrl+Shift+F10` (Eclipse), `⌃ ⇧ R` (Eclipse (macOS)) 在测试类中重新运行这两个测试，而不是在单个方法中，并查看现在两个测试都通过。

![第二个测试通过](https://resources.jetbrains.com.cn/help/img/idea/2026.3/test-successful.png)

## 总结

首次以测试优先的方式编写测试需要进行一些设置——创建测试类、创建测试方法，然后创建最终将成为生产代码的代码的空实现。 IntelliJ IDEA 自动化了很多初始设置。

随着您在此流程中不断迭代，先创建测试，再进行使这些测试通过所需的更改，您将为所需的功能构建起一套完整的测试套件，以及能够满足这些需求的最简单解决方案。

## See also

### 外部链接

[Statistics and Studies: The Benefits Of Test Driven Development](https://theqalead.com/general/statistics-studies-benefits-test-driven-development/)

