第2章 第一个JUnit5测试用例:@Test注解、测试方法定义、断言基础、绿色/红色结果

2.1 原理概述

JUnit5 通过 @Test 注解将普通方法标记为可执行的测试用例。测试引擎在运行时会扫描被 @Test 修饰的方法,实例化测试类,依次执行这些方法,并收集执行结果。每个测试方法内部通过断言(Assertion)验证预期的行为,断言失败会抛出 AssertionError,测试用例标记为红色(失败);若所有断言通过且无未捕获异常,则标记为绿色(通过)。

关键概念: “绿色/红色结果” 源于测试运行器的 UI 反馈——绿色竖条表示全部通过,红色竖条表示存在失败用例,是 TDD(测试驱动开发)中快速定位问题的核心反馈信号。

2.2 实现流程

  1. 在 app/src/test 目录(Android 单元测试源码集)下创建测试类,命名通常为 XxxTest。
  2. 在测试类中定义 public、void 的普通方法,方法名建议使用 shouldXxx_whenYyy 或 testXxx 模式。
  3. 在方法上方添加 @Test 注解(来自 org.junit.jupiter.api.Test)。
  4. 在方法体内调用被测试代码,并使用断言方法验证结果。
  5. 通过 Gradle 的 testDebugUnitTest 任务或 IDE 的运行按钮执行测试,查看绿色/红色结果。

2.3 代码示例:第一个JUnit5测试用例

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CalculatorTest {

    @Test
    void shouldReturnSum_whenTwoPositiveNumbers() {
        Calculator calc = new Calculator();
        int actual = calc.add(3, 5);
        assertEquals(8, actual, "3 + 5 应等于 8");
    }

    @Test
    void shouldThrowException_whenDivideByZero() {
        Calculator calc = new Calculator();
        assertThrows(ArithmeticException.class,
                () -> calc.divide(10, 0),
                "除法分母为零应抛出算术异常");
    }
}
方法可见性: JUnit5 的测试方法不强制 public,包级私有(default)即可。但为了统一风格,建议使用 void 且无参数,因为 JUnit5 不支持带参数的 @Test 方法(参数化测试需使用 @ParameterizedTest,后续章节涉及)。

2.4 断言基础:常用API对比

断言方法 用途 失败时消息
assertEquals(expected, actual) 判断两个值相等(对对象调用 equals()) expected: <X> but was: <Y>
assertNotEquals(unexpected, actual) 判断两个值不相等 expected: not equal but was: <Y>
assertTrue(condition) 判断条件为 true expected: <true> but was: <false>
assertFalse(condition) 判断条件为 false expected: <false> but was: <true>
assertNull(object) 判断对象为 null expected: <null> but was: <obj>
assertNotNull(object) 判断对象不为 null expected: not <null>
assertThrows(exceptionType, executable) 验证执行 Executable 时抛出了指定类型的异常 Expected ... to be thrown, but nothing was thrown.

2.5 内联SVG:测试执行与结果判断流程

JUnit5 测试用例执行与结果判断流程 测试类加载 实例化测试对象 执行@Test方法 运行断言 断言成功?/ 未抛出异常? 绿色:测试通过 红色:测试失败 ⚠ 失败原因: 断言失败(AssertionFailedError) 或未捕获异常 是 否

2.6 调试与常见错误

常见错误1: 误导入 JUnit4 的 @Test 注解(org.junit.Test),导致断言方法不兼容。应使用 org.junit.jupiter.api.Test 和 org.junit.jupiter.api.Assertions。
常见错误2: 测试方法带有参数,JUnit5 标准 @Test 方法必须无参数。若需要参数化,请使用 @ParameterizedTest(第6章介绍)。
常见错误3: 断言失败时消息字符串缺失或使用 System.out.println 检查结果。正确做法是通过断言方法的最后一个参数传入自定义失败消息,便于定位。

2.7 在 Android Studio 中查看绿色/红色结果

  • 执行测试后,Run 窗口顶部显示绿色竖条(全部通过)或红色竖条(有失败)。
  • 每个测试方法前有绿色对勾或红色叉号图标。
  • 红色结果时,点击测试方法可查看堆栈跟踪,定位到断言失败的源代码行。
  • Gradle 命令行执行 ./gradlew testDebugUnitTest 后,控制台输出 BUILD SUCCESSFUL(绿色)或 BUILD FAILED(红色),并在 build/reports/tests/testDebugUnitTest/index.html 生成 HTML 报告。

2.8 性能与稳定性提示

  • 每个测试方法应保持独立、无顺序依赖,避免共享可变状态(参考第4章生命周期)。
  • 断言数量适当,不推荐在单个测试中做上百个断言;若需验证复杂对象,使用 assertAll() 分组(第3章)。
  • 避免在 @Test 方法内使用 Thread.sleep() 等待,应使用测试工具如 Awaitility 或 CountDownLatch 控制异步。