一、单元测试
单元测试是针对最小的功能单元编写的测试代码,对于Java来说最小的功能单元是方法,因此单元测试对于Java 来说就是针对单个Java方法的测试。
单元测试测试的基本思路是TDD(Test-Driven Development)测试驱动开发,通过测试驱动开发,提升开发质量。
单元测试的好处: 1、确保单个方法运行正常; 2、修改方法的代码后,单元测试可以快速自测; 3、可以自动化运行所有单元测试并获得报告; 4、单元测试代码可以直接用来演示方法的调用和执行;
二、Junit
Junit 当前版本:3.x / 4.x / 5.x
待测试的类及方法
public class Calculator{
public int calculate(String expression){
String[] ss = expression.split("\\+");
System.out.println(expression + " -> " + Arrays.toString(ss))
int sum = 0;
for(String s : ss){
sum = sum + Integer.parseInt(s);
}
return sum;
}
}
测试类及方法
public class CalculatorTest{
@Test
public void testCalculate(){
}
@Test
public void testCalculate(){
assertEquals(3,new Calculator.calculate("1+2"));
assertEquals(6,new Calculator.calculate("1+2+3"));
assertEquals(35,new Calculator.calculate("12+23"));
}
@Test
public void testCalculate(){
assertEquals(3,new Calculator.calculate("1 +2"));
}
}
常用断言
断言判断 | assert |
---|
断言相等 | assertEquals(100,x) | 断言数组相等 | assertArrayEquals({100,200,300},x) | 浮点数相等 | assertEquals(3.14159,x,0.0001) | 断言为 null | assertNull(x) | 断言为true/false | assertTrue(x>0) assertFalse(x>0) | 其他 | assertNotNull / assertNotEquals |
注意: 1、Junit 使用Assert 断言测试结果(浮点数assertEquals要制定delta); 2、每个测试方法必须完全独立; 3、测试代码必须非常简单; 4、不能为测试代码再编写测试; 5、方法输入场景考虑需要全面,才能起到单测效果;
三、常用注解
注解 | 解释 | 执行逻辑 | 常用场景 |
---|
@Before | 初始化测试资源 | 在每一个测试方法执行前执行 | 初始化测试对象,例如 input = new FileInputStream(); | @After | 释放测试资源 | 在每一个测试方法执行后执行 | 销毁@Before创建的测试对象,例如 input.close(); | @BeforeClass | 初始化静态资源 | 在所有测试方法执行前执行 | 初始化非常耗时的资源,例如,创建数据库 | @AfterClass | 释放静态资源 | 在所有测试方法执行后执行 | 清理@BeforeClass创建的资源,例如:删除数据库 |
以上注解Junit 执行逻辑
invokeBeforeClass(CalculatorTest.class);
for(Method testMethod : findTestMethods(CalculatorTest.class)){
CalculatorTest test = new CalculatorTest();
test.setUp();
testMethod.invoke(test);
test.tearDown();@After
}
invokeAfterClass(CalculatorTest.class);
四、异常测试
@Test(expected = NumberFormatException.class)
public void testNumberFormatException(){
Integer.parseInt(null);
}
五、参数化测试
若待测试的输入和输出是一组数据 1、可以把测试数据组织起来; 2、用不同的测试数据调用相同的测试方法;
@RunWith(Parameterized.class)
public class AbsTest{
@Parameters
public static Collection<?> data(){
return Arrays asList(new Object[][]{{0,0},{1,1},{-1,1}});
}
int input ;
int expected;
public AbsTest(int input,int expected){
this.input = input;
this.expected = expected;
}
@Test
public void testAbs(){
int r = Math.abs(this.input);
assertEquals(this.expected, r);
}
}
参数必须由静态方法data() 返回,返回类型为Collection<Object[]> 静态方法必须标记为@Parameters 测试类必须标记为@RunWith(Parameterized.class) ,构造方法参数必须和测试参数对应。
六、超时测试
public class PItest{
PI pi = new PI();
@Test(timeout=1000)
public void testTimeout(){
double r = pi.calculate(1000);
assertEquals(3.14, r , 0.01);
}
}
|