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定义类中的所有测试用例。