跳转到内容

Java测试注解

来自代码酷

Java测试注解[编辑 | 编辑源代码]

Java测试注解是Java单元测试框架(如JUnit和TestNG)中用于标记测试方法、配置测试环境及控制测试流程的特殊标记。它们为测试代码提供元数据,使测试框架能够识别和执行特定的测试逻辑。本指南将详细介绍常见的Java测试注解及其用法。

核心注解[编辑 | 编辑源代码]

以下是JUnit 5(当前主流版本)中最常用的测试注解:

@Test[编辑 | 编辑源代码]

标记一个方法为测试方法。测试框架会自动执行所有带有此注解的方法。

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

class CalculatorTest {
    @Test
    void testAddition() {
        Calculator calc = new Calculator();
        assertEquals(5, calc.add(2, 3));  // 预期值, 实际值
    }
}

输出: 若测试通过则无输出(静默成功),失败时会显示详细比较信息。

@BeforeEach / @AfterEach[编辑 | 编辑源代码]

分别在每个测试方法之前/之后执行:

@BeforeEach
void setUp() {
    System.out.println("初始化测试环境");
}

@AfterEach
void tearDown() {
    System.out.println("清理资源");
}

@BeforeAll / @AfterAll[编辑 | 编辑源代码]

所有测试方法之前/之后执行(方法需为static):

@BeforeAll
static void initDatabase() {
    System.out.println("连接数据库");
}

高级注解[编辑 | 编辑源代码]

@DisplayName[编辑 | 编辑源代码]

为测试类或方法设置易读的名称:

@Test
@DisplayName("测试除法→零除异常")
void testDivisionByZero() {
    assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0));
}

@ParameterizedTest[编辑 | 编辑源代码]

参数化测试,允许使用不同参数多次运行测试:

@ParameterizedTest
@ValueSource(ints = {1, 3, 5, -3})
void testIsOdd(int number) {
    assertTrue(NumberUtils.isOdd(number));
}

@Nested[编辑 | 编辑源代码]

创建嵌套测试类,展示测试层次结构:

class StackTest {
    Stack<Object> stack;

    @Nested
    class WhenNew {
        @BeforeEach
        void createStack() {
            stack = new Stack<>();
        }

        @Test
        void isEmpty() {
            assertTrue(stack.isEmpty());
        }
    }
}

生命周期图示[编辑 | 编辑源代码]

graph TD A[@BeforeAll] --> B[@BeforeEach] B --> C[@Test] C --> D[@AfterEach] D --> E[@Test] E --> F[@AfterEach] F --> G[@AfterAll]

实际案例:用户服务测试[编辑 | 编辑源代码]

class UserServiceTest {
    UserService service;
    User testUser;

    @BeforeEach
    void init() {
        service = new UserService();
        testUser = new User("admin", "secret");
    }

    @Test
    @DisplayName("成功登录应返回用户令牌")
    void testSuccessfulLogin() {
        String token = service.login(testUser.username(), testUser.password());
        assertNotNull(token);
        assertTrue(token.length() > 10);
    }

    @Test
    @DisplayName("错误密码应抛出异常")
    void testWrongPassword() {
        assertThrows(AuthenticationException.class, 
            () -> service.login(testUser.username(), "wrong"));
    }
}

TestNG特有注解[编辑 | 编辑源代码]

虽然JUnit更常见,但TestNG也有独特注解:

  • @BeforeSuite/@AfterSuite - 测试套件前后执行
  • @DataProvider - 更灵活的参数化测试
  • @Test(dependsOnMethods = "...") - 定义测试依赖关系

最佳实践[编辑 | 编辑源代码]

1. 每个测试方法应只测试一个功能点 2. 使用@DisplayName提高测试报告可读性 3. 初始化代码放在@BeforeEach而非构造函数中 4. 避免在静态@BeforeAll方法中修改可变状态

数学公式示例[编辑 | 编辑源代码]

当测试涉及数学计算时,可注明预期公式: E=mc2

通过掌握这些注解,您可以构建结构清晰、维护性强的单元测试套件。随着测试复杂度的增加,还可以探索更高级的注解如@Tag用于测试分类、@Timeout用于超时控制等。