单元测试的概念:单元测试是对一个单一实体(类或者方法)的测试,用来验证该单一实体是否按照需求正确执行。
JUnit:JUnit是一个Java编程语言的单元测试框架。
l 提供注释来识别测试方法。
l 提供断言来测试预期结果。
l 提供测试运行来运行测试。
l JUnit 测试可以被组织为测试套件,包含测试用例,甚至其他的测试套件。
TIPS:快速生成一个类中所有方法的JunitTest Case:选中要测试的类 > 右键 > New > Junit Test Case [>修改package,修改Name] > Next > 选择要测试的方法 >Finish
JUnitTest Case类:
l 使用注解@BeforeClass、@AfterClass 、@Before、@After、@Test(注解说明见下文)
l @Test将一个普通的方法标记为测试方法,在该方法中实现单元测试
l 在@Test的方法中使用断点,判断测试执行结果是否符合预期
publicclass CalculatorTest {
@Test
publicvoid testAdd() {
assertEquals(5, new Calculator().add(2, 4));
}
@Test
publicvoid testAdd_1() {
assertEquals(6, new Calculator().add(2, 4));
}
}
几种注解的说明:
@BeforeClass – 表示在类中的任意public staticvoid方法执行之前执行,且只执行一次
@AfterClass – 表示在类中的任意public staticvoid方法执行之后执行,且只执行一次
@Before – 表示在任意使用@Test注解标注的publicvoid方法执行之前执行,每个@Test方法执行之前都会执行一次
@After – 表示在任意使用@Test注解标注的publicvoid方法执行之后执行,每个@Test方法执行之后都会执行一次
@Test – 使用该注解标注的public void方法会表示为一个测试方法
@RunWith和 @Suite:捆绑几个测试案例并且同时运行,使用方法如下
l 新建测试类,如CalculatorTest和CalculatorTest1
l 新建测试套件TestSuite
l 实现测试套件,代码如下
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorTest.class,CalculatorTest1.class})
publicclass TestSuite {
publicvoid test() {
}
}
使用JUnitCore.runClasses执行Junit测试:
publicclass TestSuite {
publicstaticvoid main(String[] args) {
Result result = JUnitCore.runClasses(CalculatorTest.class, CalculatorTest1.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.getMessage());
}
}
}
利用测试套件执行单元测试的方法:
l 创建被测试类
l 创建Test Case类
l 创建Test Suite类
l 创建Test Runner类
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
importorg.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
@Ignore注解忽略测试,用于被测试类还没有全部准备好的场景:
l 一个含有 @Ignore 注释的测试方法将不会被执行。
l 如果一个测试类有@Ignore 注释,则它的测试方法将不会执行。
Junit时间测试:如果一个测试用例比起指定的毫秒数花费了更多的时间,那么 Junit 将自动将它标记为失败,使用方式为在@Test注解中增加参数“timeout=超时时间”,例如:
@Test(timeout=1000)
publicvoid testAdd() {
assertEquals(1, new Calculator().add(1, 1));
}
Junit异常测试:类似于Junit时间测试,修改@Test注解的参数为“expected=预期抛出异常的类”,用来追踪异常的选项,可以测试代码是否它抛出了想要得到的异常,如:
@Test(expected=NullPointerException.class)
publicvoid testAdd() {
assertEquals(1, new Calculator().add(1, 1));
}
Junit参数化测试:Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试
l 用@RunWith(Parameterized.class) 来注释 Test Case类。
l 创建一个由@Parameters 注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合。
l 为每一个测试数据创建一个实例变量。
l 创建一个公共的构造函数,它接受和一行测试数据相等同的东西。
l 用实例变量作为测试数据的来源来创建你的测试用例。
可见参数化测试重点在于Test Case类的创建,如下示例创建了三组测试数据:
@RunWith(Parameterized.class)
publicclass CalculatorTest2 {
privateintexpected = 0, input1 = 0, input2 = 0;
@Parameters
publicstatic Collection<Object[]> test() {
return Arrays.asList(new Object[][]{{4, 1, 3}, {5, 2, 3}, {6, 3,3}});
}
public CalculatorTest2(intexpected, intinput1, intinput2) {
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
}
@Test
publicvoid testAdd() {
assertEquals(expected, new Calculator().add(input1, input2));
}
}
JunitANT插件:该插件可以用来在命令行中执行测试用例,并生成测试结果
MOCK(easymock, mockito, powermock, jmockito)
Mock说白了就是打桩(Stub)或者模拟,当你调用一个不好在测试中创建的对象时,Mock框架为你模拟一个和真实对象类似的替身来完成相应的行为。如希望对UserServiceImpl进行测试,而UserDao开发组只给出接口,尚未完成功能实现,则可以使用Mock对UserDao进行模拟来测试UserServiceImpl。