发表于: 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的用法,以后测试代码可以省下一些力气去写测试类了,而且具体某个单独的方法也可以单独测试,不用再一个一个分开调用来测试。


返回列表 返回列表
评论

    分享到