搞定Java单元测试!从JUnit4开始入门
1.基础架构
被测代码:Calculator.java
package JUnit.com.jerry;
public class Calculator {
private static int result; // 静态变量,用于存储运行结果
public void add(int n) {
result = result + n;
}
public void substract(int n) {
result = result - n;
}
public void multiply(int n) {
result = result * n;
}
public void divide(int n) {
result = result / n;
}
public void square(int n) {
result = n * n;
}
public void squareRoot(int n) {
for (; ;) ; //Bug : 死循环
}
public void clear() { // 将结果清零
result = 0;
}
public int getResult() {
return result;
}
}
基本的测试代码:CalculatorTest.java
package JUnit.com.jerry;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class CalculatorTest {
private static Calculator calculator = new Calculator();
@Before
public void setUp() throws Exception {
calculator.clear();
}
@Test
public void testAdd() {
calculator.add(2);
calculator.add(3);
assertEquals(5, calculator.getResult());
}
@Test
public void testSubstract() {
calculator.add(5);
calculator.substract(3);
assertEquals(2, calculator.getResult());
}
@Test
public void testMultiply() {
calculator.add(3);
calculator.multiply(2);
assertEquals(6, calculator.getResult());
}
@Test
public void testDivide() {
calculator.add(9);
calculator.divide(3);
assertEquals(3, calculator.getResult());
}
2. JUnit4的修饰符
修饰符 |
含义 |
---|---|
@Before |
每个用例前执行 |
@Test |
下面是一个测试用例 |
@After |
每个用例后执行 |
@BeforeClass |
类中所有用例前执行 |
@AfterClass |
类中所有用例后执行 |
@Ignore |
测试类或测试方法不执行 |
@Categories |
表示单元测试类别 |
3. JUnit4的断言
断言方法 |
断言描述 |
---|---|
assertEquals([String message],expected,actual) |
expected==actual,测试通过(用于整型数字) |
assertEquals([String message],expected,actual,tolerance) |
expected==actual,测试通过,tolerance为浮点数的精度 |
assertTrue ([String message],Boolean condition) |
condition条件成立,测试通过 |
assertFalse([String message],Boolean condition) |
condition条件不成立,测试通过 |
assertNull([String message],Object object) |
object为空,测试通过 |
assertNotNull([String message],Object object) |
Object不为空,测试通过 |
assertSame ([String message],expected,actual) |
expected与actual相同,测试通过 |
assertNotSame ([String message],expected,actual) |
expected与actual相同,测试通过 |
fail([String message]) |
直接直接失败 |
4. 延迟测试
@Test(timeout=1000 ) //1000毫秒
Public void squareRoot() {
calculator.squareRoot(4);
assertEquals(2 , calculator.getResult());
}
由于squareRoot方法是一个死循环,为了保证测试用例不至于无限制等待,在@Test后使用(timeout=1000),意思是等待1000毫秒,如果1000毫秒内没有出结果,默认测试失败
5. 参数化测试
package JUnit.com.jerry;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class )
public class SquareTest {
private static final Object[] String = null;
private static Calculator calculator = new Calculator();
private int param;
private int result;
@Parameters
public static Collection data() {
return Arrays.asList( new Object[][] {
{ 2 , 4 } ,
{ 0 , 0 } ,
{-3 , 9 } ,
{-15 , 225 } ,
} );
}
// 构造函数,对变量进行初始化
public SquareTest( int param, int result) {
this.param=param;
this.result =result;
}
@Test
public void square() {
calculator.square(param);
assertEquals(result, calculator.getResult());
}
}
参数化测试必须使用Parameterized.class运行器,参数化方法使用
@Parameters装饰器。
6. @BeforeClass和@AfterClass
public class CalculatorTest {
@BeforeClass
public void setUp() throws Exception {
db.connect();
}
@Before
…
@test
…
@After
…
@AfterClass
public void tearDown() throws Exception {
db.disconnect();
}
由于所有的测试用例开始都要连接数据库,结束后都要断开数据库,这个时候如果使用@Before和@After装饰符势必会测试执行的速度,JUnit4提供了@BeforeClass和@AfterClass,可以帮助解决这种情况。
7. 批量运行
import org.JUnit.runner.RunWith;
import org.JUnit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
CalculatorTest.class,
SquareTest.class
} )
public class AllCalculatorTests{
}
使用Suite.class运行器,可以依次运行Suite.SuiteClasses定义类中的所有测试用例。
上一篇: NDK单元测试在Android中的应用
下一篇: 单元测试&依赖注入