Junit4概述
JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何完成功能和完成什么样的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。
Junit4快速使用
- 测试方法上使用@Test进行修饰
- 测试方法上必须使用public void 进行修饰,不能带任何参数
- 新建Junit Test Case,并放在测试目录中
- 测试类的包名与被测试的包名保持一致
- 测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖
- 测试类使用Test作为类名的后缀(规范)
- 测试方法使用test作为方法名的前缀(规范)
public class AlgorithmTest {
@Test
public void test() {
fail("Not yet implemented");
}
//运用断言测试
@Test
public void testAdd(){
assertEquals(5, new Algorithm().add(3,3));
}
@Test
public void testDivide(){
assertEquals(6, new Algorithm().divide(6, 0));
}
// JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
assertThat("albumen", both(containsString("a")).and(containsString("b")));
}
// Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers() {
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
}
测试失败的情况:
1. Failure一般有单元测试使用的断言方法判断失败所引起的,这表示测试点发现了问题,程序输出的结果和我们预期的不一样.
2. error是由代码异常引起的,它可以产生于测试代码本身的错误,也就是被测试代码中的bug.
理解:测试用例不是用例证明你是对的,而是用来证明你没有错!
Matchers(匹配器) and assertthat
通用语法:assertThat([value], [matcher statement]);
更强的可读性和类型多样化:这种语法允许你在主体,动词,对象 (assert “x is 3”) 而不是assertEquals,它使用动词,对象,主体(assert “equals 3 x”)
可组合:任何匹配语句可以被否定(not(s)),组合(either(s).or(t)),映射到集合(each(s))或者在自定义组合中使用(afterFiveSeconds(s)
)。
Junit4常用注解
- @Test : 测试方法,测试程序会运行的方法,后边可以跟参数代表不同的测试,如(expected=XXException.class) 异常测试,(timeout=xxx)超时测试
- @Ignore : 被忽略的测试方法
- @Before: 每一个测试方法之前运行
- @After : 每一个测试方法之后运行
- @BeforeClass: 所有测试开始之前运行,可以用于加载配置文件等资源
- @AfterClass: 所有测试结束之后运行,可用于释放资源
@Test
@Test(expected = IndexOutOfBoundsException.class)
public void empty() {
System.out.println(new ArrayList<Object>().get(0));
}
使用ExpectedException规则。此规则允许您不仅指示期望的异常,而且还指示您期望的异常消息。
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
list.get(0); // execution will never get past this line
}
@Test(timeout=1000)
public void testWithTimeout(){
while (true) {
System.out.println("Hello World");
}
}
设置方法测试时间:
public static String log;
@Rule
public Timeout globalTimeout = Timeout.seconds(10); // 每个方法最多测试10秒
@Test
public void testSleepForTooLong() throws Exception {
log += "ran1";
TimeUnit.SECONDS.sleep(5); // 睡眠5秒,超过10秒就会报错
}
@Ignore
@Ignore("测试被忽略")
@Test
public void testSame() {
assertThat(1, is(1));
}
Test fixtures
public class FixturesTest {
static class ExpensiveManagedResource implements Closeable {
public void close() throws IOException {}
}
static class ManagedResource implements Closeable {
public void close() throws IOException {}
}
@BeforeClass
public static void setUpClass() {
System.out.println("@BeforeClass 加载类前运行");
myExpensiveManagedResource = new ExpensiveManagedResource();
}
@AfterClass
public static void tearDownClass() throws IOException {
System.out.println("@AfterClass 销毁类后运行");
myExpensiveManagedResource.close();
myExpensiveManagedResource = null;
}
private ManagedResource myManagedResource;
private static ExpensiveManagedResource myExpensiveManagedResource;
private void println(String string) {
System.out.println(string);
}
@Before
public void setUp() {
this.println("@Before 每个测试方法前运行");
this.myManagedResource = new ManagedResource();
}
@After
public void tearDown() throws IOException {
this.println("@After 每个测试方法后运行");
this.myManagedResource.close();
this.myManagedResource = null;
}
@Test
public void test1() {
this.println("@Test test1()");
}
@Test
public void test2() {
this.println("@Test test2()");
}
}
运行结果:
@BeforeClass 加载类前运行
@Before 测试方法前运行
@Test test1()
@After 测试方法后运行
@Before 测试方法前运行
@Test test2()
@After 测试方法后运行
@AfterClass 销毁类后运行
Junit4测试套件与参数化设置
Suite
使用Suite作为运行器允许您手动构建一个包含许多类的测试的套件,当你运行这个类,它将运行所有套件类中的所有测试。
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestFeatureLogin.class,
TestFeatureLogout.class,
TestFeatureNavigate.class,
TestFeatureUpdate.class
})
public class FeatureTestSuite {
// 这个类必须为空,
// 只能用于上面注解的类
}
Parameterized
运行器Parameterized实现参数化测试。
当运行参数化测试类时,测试方法和测试数据的交叉实例被创建.
/**
* 斐波那契数列
*/
public class Fibonacci {
public static int compute(int n) {
int result = 0;
if (n <= 1) {
result = n;
} else {
result = compute(n - 1) + compute(n - 2);
}
return result;
}
}
//斐波那契数列测试
@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }
});
}
private int fInput;
private int fExpected;
public FibonacciTest(int input, int expected) {
fInput= input;
fExpected= expected;
}
@Test
public void test() {
assertEquals(fExpected, Fibonacci.compute(fInput));
}
}
Junit4与Spring整合
导入maven坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Junit4与Spring整合测试
public class SpringTest {
private static ApplicationContext context;
@BeforeClass
public static void setUpBeforClass()throws Exception{
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test(){
Date date = (Date) context.getBean("date");
System.out.println(date);
}
}
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<bean id="date" class="java.util.Date" />
</beans>
还可以整合Hibernate等其它框架进行测试。