企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
> 本章介绍 JUnit4 的最佳实践,常用注解以及运行流程 1. 完善代码——JUnit最佳实践 ```java package com.dodoke; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * 计算器测试类 */ public class CalculatorTest { private Calculator calculator; // 执行测试方法之前调用,初始化计算器类实例 @Before public void setUp() throws Exception { calculator = new Calculator(); } // 测试加法 @Test public void testSum() throws Exception { long result = calculator.sum(10, 3); Assert.assertEquals(13L, result); } // 测试减法 @Test public void testSubtract() throws Exception { long result = calculator.subtract(10, 3); Assert.assertEquals(7L, result); } // 测试乘法 @Test public void testMultiply() throws Exception { long result = calculator.multiply(10, 3); Assert.assertEquals(30L, result); } // 测试除法 @Test public void testDivide() throws Exception { double result = calculator.divide(10, 2); Assert.assertEquals(10 / 2, result, 1E-10); } } ``` - 测试方法上必须使用 @Test 注解修饰 - 测试方法必须使用 public void 进行修饰,不能带任何的参数 - 新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开 - 测试类所在的包名应该和被测试类所在的包名保持一致 - 测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖 - 测试类使用 Test 作为类名的后缀(不是必须) - 测试方法使用 test 作为方法名的前缀(不是必须) 2. 测试失败的两种情况 - 测试用例不是用来证明你是对的,而是用来证明你没有错。 - 测试用例用来达到想要的预期结果,但对于逻辑错误无能为力。 - Failure: 一般有单元测试使用的断言方法判断失败所引起的。这仅仅表示测试点发现了问题,就是说程序输出结果和我们预期的不一样。 - Error: 是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中的bug。 ```java package com.dodoke; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * 错误和失败测试类 */ public class ErrorAndFailureTest { private Calculator calculator; @Before public void setUp() throws Exception { calculator = new Calculator(); } @Test public void testDivide() throws Exception { Assert.assertEquals(10.0 / 3, calculator.divide(10, 3), 1E-10); // Assert.assertEquals(10.0 / 0, calculator.divide(10, 0), 1E-10); } } ``` ``` // 运行结果 1 java.lang.AssertionError: Expected :3.3333333333333335 Actual :3.0 ``` ``` // 运行结果 2 java.lang.ArithmeticException: by zero ``` 3. JUnit运行流程 - @BeforeClass: 修饰的方法必须要是静态方法,会在所有方法被调用前被执行,当测试类被加载后接着就会运行它,而且在内存中它只会存在一份实例,它比较适合加载配置文件。 - @AfterClass: 修饰的方法必须要是静态方法,会在所有测试结束之后运行,通常会用来对资源的清理,如关闭数据库的连接。 - @Before: 每一个测试方法之前运行 - @After: 每一个测试方法之后运行 ```java package com.dodoke; import org.junit.*; /** * JUnit流程测试类 */ public class JUnitFlowTest { @BeforeClass public static void testBeforeClass() throws Exception { System.out.println("BeforeClass"); } @AfterClass public static void testAfterClass() throws Exception { System.out.println("AfterClass"); } @Before public void testBefore() throws Exception { System.out.println("Before"); } @After public void testAfter() throws Exception { System.out.println("After"); } @Test public void testTest() throws Exception { System.out.println("Test"); } } ``` ``` BeforeClass Before Test After AfterClass ``` 4. JUnit常用注解 - @Test: 将一个普通的方法修饰成为一个测试方法 - @Test(expected=XXException.class) 预期异常 - @Test(timeout=xx(毫秒)) 耗费时间 - @BeforeClass: 它会在所有的方法运行前被执行,static修饰 - @AfterClass: 它会在所有的方法运行后被执行,static修饰 - @Before: 会在每一个测试方法被运行前执行一次 - @After: 会在每一个测试方法运行后执行一次 - @Ignore: 所修饰的方法会被测试运行器忽略 - @RunWith: 可以更改测试运行器 org.junit.runner.Runner ```java @Test(expected = ArithmeticException.class) public void testExpected() throws Exception { double result = new Calculator().divide(10, 0); Assert.assertEquals(10.0 / 3, result, 1E-10); } @Test(timeout = 1) public void testTimeout() throws Exception { long result = new Calculator().sum(10, 3); Assert.assertEquals(13L, result); } @Ignore public void testIgnore() throws Exception { System.out.println("Ignore"); } ``` ``` // testTimeout 测试结果 org.junit.runners.model.TestTimedOutException: test timed out after 1 milliseconds ```