Java、JUnit、单元测试,最佳实践,测试自动化
1. 确保原子性和独立性
单元测试应该是原子化的,也就是说,一个测试只测试一个特定的功能。它们也应该相互独立,以确保失败或成功不会影响其他测试。
@Test public void testDeposit() { // 设置测试数据 Account account = new Account(); // 实施被测方法 account.deposit(100); // 验证结果 assertEquals(100, account.getBalance()); }
2. 使用断言而不是异常
用断言代替异常来验证失败,因为它们更清晰,更容易阅读。
@Test public void testWithdraw() { // 设置测试数据 Account account = new Account(); account.deposit(100); // 实施被测方法 try { account.withdraw(101); fail("Expected InsufficientFundsException"); } catch (InsufficientFundsException e) { // 断言成功 } }
3. 覆盖所有代码路径
单元测试应覆盖被测代码的所有路径,包括正常和异常情况。
@Test public void testToString() { // 设置测试数据 Account account = new Account(); // 实施被测方法 String result = account.toString(); // 验证结果 assertTrue(result.contains("Account")); }
4. 使用 Mocking 和 Stubbing
嘲笑和Stubbing允许您将被测代码隔离,模拟外部依赖项的行为。
@Test public void testTransfer() { // 嘲笑 TransferService TransferService transferService = Mockito.mock(TransferService.class); // 设置测试数据 Account account1 = new Account(); Account account2 = new Account(); // 实施被测方法 account1.transfer(100, account2); // 验证 TransferService 被调用 Mockito.verify(transferService).transfer(account1, account2, 100); }
5. 使用 ExpectedException 断言
ExpectedException 断言允许您验证该方法是否抛出了预期的异常。
@Test(expected = InsufficientFundsException.class) public void testWithdrawInsufficientFunds() { // 设置测试数据 Account account = new Account(); // 实施被测方法 account.withdraw(101); }
6. 避免使用 sleep()
sleep() 不确定性将引入单元测试,应避免使用。使用 TestRule 或 MockClock 控制时间等待替代方案。
7. 重构代码以提高可测性
将代码重构成更可测试的形式,消除测试的复杂性。
// 移动私有方法 public 类中 class AccountUtils { public static boolean isEligibleForInterest(Account account) { // ... } }
8. 使用参数测试
参数测试允许您使用一组数据来操作相同的测试,从而节省时间。
@ParameterizedTest @CsvSource({ "100, 50", "200, 100", "300, 150" }) public void testWithdraw(int initialBalance, int amount) { // ... }
9. 使用 TestWatcher
TestWatcher 允许您在测试前或测试后执行自定义操作。
public class CustomTestWatcher extends TestWatcher { @Override protected void failed(Throwable e, Description description) { // ... } }
10. 遵循命名协议
遵循一致的测试方法命名协议,例如 "test" 为了提高可读性和可维护性,开头和使用描述性清晰的名称。