1.写测试类的原则
测试方法上必须使用@Test进行修饰;
测试方法必须使用public void 进行修饰,不能带任何的参数;
新建一个源代码目录来存放我们的测试代码;
测试类的包应该和被测试类的包保持一致;
测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖;
测试类使用Test作为类名的后缀(不是必须);
测试方法使用test作为方法名的前缀(不是必须)
2.测试用例不是用来证明你是对的,而是用来证明你没有错
测试失败的两种情况:Error和Failure。
Failure一般由单元测试使用的断言方法判断失败所引起的,这表示测试点发现了问题,就是说程序输出的结果和我们预期的不一样,比如,除法中的除数不能为0,若为0就会出现Failure.
Error是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中隐藏的一个bug
测试用例不是用来证明你是对的,而是用来证明你没有错。
3.JUnit的运行流程
是@BeforeClass,@before,@test1,@after,@before,@test2,@after,@AfterClass
@beforeClass修饰的方法会在所有方法被调用前执行,而且该方法是静态的,所以当测试类被加载后接着就会运行它,而且在内存中它只会存在一份实例,它比较适合加载配置文件
@AfterClass所修饰的方法通常用来对资源的清理,如关闭数据库的连接
@Before和@After会在每个测试方法的前后各执行一次
4.JUnit中的常用注解
@Test将一个普通的方法修饰成为一个测试方法
@Test(expected=XX.class),比如出现除数为0的情况,可以使测试通过
@Test(timeout=毫秒),比如用在死循环中,通过设置timeout可以使循环停下来
@Before会在所有方法的运行前被执行,static修饰
@AfterClass会在所有的方法运行结束后被执行,static 修饰
@Before:会在每个测试方法被运行前执行一次
@After:会在每个测试方法运行后被执行一次
@Ignore:所修饰的测试方法会被测试运行器忽略,不会被执行
@RunWith:可以更改测试运行器
5.JUnit测试:
JUnit 3.x 版本通过对测试方法的命名(test+方法名)来确定是否是测试,且所有的测试类必须继承TestCase.JUnit 4.x版本全面 引入了注解来执行我们编写的测试,JUnit 中有两个重要的类(Assume和Assert),以及其他一些重要的注解(BeforeClass AfterClassAfter Before Test 和 Ignore).其中,BeforeClass和AfterClass在每个类加载的开始和结束时运行,需要设置static方法, 而Before和After则在每个测试方法开始之前和结束之后运行.
代码片段如下:
import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.*;
public class Testing {
@BeforeClass
public static void beforeClassTest(){
System.out.println("单元测试开始之前执行初始化......");
System.out.println("-----------------------------");
}
@Before
public void beforeTest(){
System.out.println("单元测试方法开始之前执行......");
}
@Test
public void test1(){
Date sd = DateFormatUtils.formatStr2Date("2018-05-16");
Date ed = DateFormatUtils.formatStr2Date("2018-05-25");
System.out.println("相差天数: " + DateFormatUtils.getBetweenDays(sd,ed));
assertEquals("相差天数: " , 9, DateFormatUtils.getBetweenDays(sd,ed));
}
@Test
public void test2(){
Date sd = DateFormatUtils.formatStr2Date("2018-05-16");
Date ed = DateFormatUtils.formatStr2Date("2018-09-30");
System.out.println("相差天数: " + DateFormatUtils.getBetweenDays(sd,ed));
assertEquals("相差天数: " , 9, DateFormatUtils.getBetweenDays(sd,ed));
}
@After
public void afterTest(){
System.out.println("单元测试方法结束后执行......");
}
@AfterClass
public static void afterClassTest(){
System.out.println("-----------------------------");
System.out.println("单元测试开始之后执行......");
}
}
JUnit在执行每个@Test方法之前,会为测试类创建一个新的实例.这有助于提供测试方法之间的独立性,并且避免在测试代码中产生意外的副作用.因为每个测试方法都运行与一个新的测试类的实例上,所以不能再测试方法之间重用各个实例的变量值.
以上代码Test2未通过测试,因为我们输入的预期值为9天,实际上为127天,这一点可以从错误结果看出.
6.JUnit没有main()方法作为入口是怎么运行的?
其实在org.junit.runner包下有个JUnitCore.class,其中就有一个是标准的main方法,这就是JUnit入口函数.如此看来,它其实和我们直接在自己的main方法中跑我们要测试的方法在本质上是一样的.
7.Assert
为了进行测试验证,我们使用了JUnit的Assert类提供的assert方法.正如之前在实例中所看到的那样,我们在测试类中静态地导入了这些方法.另外,根据我们队静态导入的喜好,还可以导入JUnit的Assert类本身,下面是一些常用的assert方法:
8.Suite
JUnit设计Suite的目的是一次性运行一个或多个测试用例,Suite是一个容器,用来把几个测试类归在一起,并把他们作为一个集合来运行,测试运行器会启动Suite,而运行哪些测试类由Suite决定.
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({TestSuite1.class, TestSuite2.class})
public class TestSuiteMain {
// 虽然这个类是空的,但依然可以运行JUnit测试,运行时,它会将Testsuite1.class和TestSuite2.class中
// 所有的测试用例都执行一遍.
}