发表于: 2018-03-31 15:51:32
1 623
今天完成的事:
junit的学习和使用:
先去github上下载了两个jar包,分别是junit-4.12.jar和hamcrest-core-1.3.jar
导入到modules里的Dependencies下
创建一个com.xiuzhenyuan,util.Math类,然后输入一个求阶乘的方法;
再创建一个对Math方法的单元测试:创建一个和src同级别的文件夹test(逻辑代码放src里,测试代码放test里是个好习惯),然后右键文件夹,Mark DIrectory As-Test Sources Root;
通过快捷键ctrl+shift+T创建测试类,因为我之前创建好了,所以这里就会显示已经有一个了
添加测试方法,ctrl+shift+F10快捷键运行测试类
绿色表示测试通过,如果把120改成别的数字那么就会测试不通过,显示红色。Junit有一句话叫做:”keep the bar green to keep the code clean“
这里解释以下MathTest:
Ⅰ导入了org.junit.Test和org.junit.Assert.*两个包,注意后者是静态导入import static
Ⅱ所有测试方法返回类型必须为void且无参数
Ⅲ每个测试方法前面都会有”@Test“这个注解,代表这是个测试方法
ⅣassertEquals的作用是判断两个参数是否相等,图中120是预期结果,new Math().factorial(5)是实际结果。但是通常不应该只比较一个值,要多测试几个特殊值,特别是临界值,例如Math().factorial(0)和Math().factorial(-1)等
ⅤassertEquals除了比较两个int,还重载了好多次不同类型的参数的比较。而且Junit包含一堆assertXXX方法,assertEquals只是其中之一,这些assertXXX统称为断言,下图是junit-4.12-javadoc.jar文档下的index.html打开后查找到的断言资料
前面提到了Junit的注解,下面介绍下几个常用的注解:
①@Test:把每一个方法标记为测试方法
②@Before:每一个测试方法执行之前自动调用一次
③@After:每一个测试方法执行完成之后自动调用一次
④@BeforeClass:所有测试方法执行前执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
⑤@AfterClass:所有测试方法执行完成之后执行一次,在测试类还没有实例化就已经被加载,所以用static修饰
⑥@Ignore:暂不执行该测试方法
尝试下各个注解的应用,新建一个测试类AnnotationTest,每个注解都使用到,@Test使用两次,分别是test1和test2,用@Ignore注解test3
下面是具体的代码:
package com.xiuzhenyuan.util;
import org.junit.*;
public class AnnotaionTest {
public AnnotaionTest(){
System.out.println("构造方法");
}
@BeforeClass
public static void setUpBoforeClass(){
System.out.println("BeforeClass...");
}
@AfterClass
public static void tearDownAfterClass(){
System.out.println("AfterClass...");
}
@Before
public void setUp(){
System.out.println("Before...");
}
@After
public void tearDown(){
System.out.println("After...");
}
@Test
public void test1(){
System.out.println("test1");
}
@Test
public void test2(){
System.out.println("test2");
}
@Ignore
public void test3(){
System.out.println("test3");
}
}
下面是运行结果:
@BeforeClass和@AfterClass在类被实例化前(构造方法执行前)就被调用了,而且只执行一次,通常用来初始化和关闭资源。@Before和@After在每个@Test执行前后都会被执行一次。被@Ignore标记的测试方法不会被执行,一般就是在忽略这个方法或者其不影响使用的时候
@Test的属性
@Test的话,其实有其独有的属性,一个是expected,另一个是timeout。expected属性是用来测试异常的,前面的Math类中的求阶乘方法factorial(),如果传进来一个负数我们是希望抛出异常的,那怎么测试会不会抛出异常呢
在MathTest中添加一个测试方法:
这个方法就是(expected=Exception.class)和(”factorial参数为负数没有抛出异常“)之间的配合。就是这个测试方法会检查是否抛出Exception异常(当然也可以检测是否抛出其他异常),如果抛出了异常那么测试通过(因为预期就是传进负数抛出异常),没有抛出异常则测试不通过,执行fail。如图,测试是通过的。
然后说下timeout属性,顾名思义就是超时属性,值是毫秒,通常用来对方法运行时间进行限定,比如一个方法进入了死循环,这时候就可以利用到timeout用来强制退出程序
这里的程序写了一个死循环,但是并没有一直持续执行,直到内存无法承受,而且在2s之后直接停止了程序;当然也可以用来做性能测试,用来测试程序的读写性能,超过一定时长,就认为程序不成功
Thread.sleep是的程序休眠2000ms,timeout的时间限制是3000ms,规定时间内完成了程序的运行,运行成功。
明天计划的事情:
学习Spring及其相关事宜
遇到的问题:
在注解那里,构造方法被执行了两次,一般一个程序只会调用一次构造方法。后来我查了以下,Junit为了保证每个测试方法都是单元测试,是独立的互补影响,所以每个测试方法执行前都会重新实例化测试类。后面我又做了实验来验证一下:
添加一个成员变量:
int i =0;
test1和test2分别改为:
@Test
public void test1(){
i++;
System.out.println("test1的i值为"+i
);
}
@Test
public void test2(){
i++;
System.out.println("test2的i值为"+i);
}
执行之后的结果:
可以看到test1和test2的i都只自增了一次,所以test1的执行不会影响test2,因为执行test2的时候又把测试类重新实例化了一遍。那如果希望test2的执行结果受到test1的影响怎么办呢,把int改成static就好了
收获:
学习了junit的用法,以后测试代码可以省下一些力气去写测试类了,而且具体某个单独的方法也可以单独测试,不用再一个一个分开调用来测试。
评论