一、关于 Junit
单元(Unit)测试API,用于开发过程中进行单元测试。
Junit 官方在线示例与下载:
https://github.com/junit-team/junit4/wiki
Junit 中文教程:
https://www.w3cschool.cn/junit/jycq1hus.html
二、基础介绍
Junit 提供了不同测试方式:断言测试、时间测试、异常测试、参数测试等。具体测试示例可在上面两个链接查看,对其中几类测试作简单介绍:
断言测试:assertXXX(),判断条件是否满足,不满足时测试结果为失败;
时间测试:测试方法的执行时间,超过指定的时间时,结果为失败;
异常测试:测试是否抛出某个具体异常,抛出异常时测试成功;
参数测试:指定一系列参数,对同一方法一次性进行多次测试。
感觉断言测试是最方便的测试,所以在此列出具体断言类型:
1、assertEquals("两参数值不相等",参数1,参数2);
2、assertArrayEquals("数组值不相等",数组1,数组2);
3、assertNull("对象不为null",对象);
4、assertNotNull("对象为null",对象);
5、assertTrue("条件为true",条件);
6、assertFalse("条件为false",条件);
7、assertSame("对象必须相同",对象1,对象2);
8、assertNotSame("对象不能相同",对象1,对象2);
9、assertThat(参数1,操作函数(参数2));此方法"操作函数"较多,不太好用。
官方例子:
public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals() {
assertEquals("failure - strings are not equal", "text", "text");
}
@Test
public void testAssertFalse() {
assertFalse("failure - should be false", false);
}
@Test
public void testAssertNotNull() {
assertNotNull("should not be null", new Object());
}
@Test
public void testAssertNotSame() {
assertNotSame("should not be same Object", new Object(), new Object());
}
@Test
public void testAssertNull() {
assertNull("should be null", null);
}
@Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
assertSame("should be same", aNumber, aNumber);
}
// JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
assertThat("albumen", both(containsString("a")).and(containsString("b")));
}
@Test
public void testAssertThatHasItems() {
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
}
@Test
public void testAssertThatEveryItemContainsString() {
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
}
// 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())));
}
@Test
public void testAssertTrue() {
assertTrue("failure - should be true", true);
}
}
三、基础实践
1、Maven 项目中使用Junit 插件。
(1)、pom.xml 中增加junit 插件依赖,默认增加了,如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
(2)、src/main/java中编写业务代码:
MyApp.java:
public class MyApp {
public int plus(int a,int b){
return a+b;
}
}
(3)、src/test/java中编写测试类继承于TestCase 类:
TestMyApp.java:
import junit.framework.TestCase;
public class TestMyApp extends TestCase {
public void testApp(){
MyApp app = new MyApp();
System.out.println("testApp");
assertTrue(app.plus(1, 2)==3);
}
public void testMyApp(){
MyApp app = new MyApp();
System.out.println("testMyApp");
assertTrue(app.plus(1, 2)==4);
}
public void runMyApp(){
MyApp app = new MyApp();
System.out.println("runMyApp");
assertTrue(app.plus(1, 2)==4);
}
}
(4)、Debug As ——>Junit Test:
至此,基本的测试就完成了,测试类中并没有使用@Test 注解(需要额外配置),所以每个测试方法的命名形式必须为testXXX(),如上面代码中的runMyApp()并没有被执行。
(5)、当编写了多个测试类时,可以用suite 方法选择测试哪一个测试类:
suite()静态方法起到调度作用:
包含suite()方法的测试类:
TestApp.java:
public class TestMyApp extends TestCase {
public static Test suite(){
return new TestSuite(TestMyAppTwo.class);//实际测试TestMyAppTwo测试类
}
//suite方法决定执行哪个测试类,起调度作用,所以此类中写测试方法没意义
public void testMyApp(){
MyApp app = new MyApp();
System.out.println("testMyApp");
assertTrue(app.plus(1, 2)==3);
}
}
TestMyAppTwo.java
public class TestMyAppTwo extends TestCase {
public TestMyAppTwo(String testName){
super(testName);
}
public void testMyAppTwo(){
System.out.println("testMyAppTwo");
MyApp app = new MyApp();
assertTrue(app.plus(1,2)==4);
}
}
Debug As——>Junit Test结果:
可以看到,TestMyAppTwo 中测试方法被运行了两次,一次是因为其本身是测试类,另一次是因被TestMyApp 类使用suite方法指定执行。但需注意的是,suite方法指定后,则没被指定的测试类不会被执行,如TestMyApp类中的testMyApp方法。
最后需说明的是,测试类的构造方法的参数含义即测试名,当将上面改为super("测试名"),运行可发现,所有测试方法都将显示为"测试名",而非按测试类名-测试方法名的形式显示。
简单总结:
1、测试类必须继承TestCase 类;
2、不使用@Test 注解时,测试方法名必须为testXXX 形式;
3、测试类中允许使用静态的public static Test suite()方法指定只执行哪个测试类。当没有使用suite 方法时,所有测试类都将被执行!
此外,确保Maven install 之前所有测试类都能通过测试,否则无法install(或说发布)成功!