单元测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试相关的知识,希望对你有一定的参考价值。

Junit

Junit目前在一些大的公司或者相对规范的软件中使用的比较多,相当多的小公司并没有把单元测试看的太重要。在大点的公司开发人员每天上班后,第一件事情就是从svn上把自己负责的代码checkout下来,然后运行单元测试,如果单元测试通过,那么说明自己的代码没有问题,然后就在代码块上修改与添加,完成后再用junit进行测试,测试完成后如果没有问题,那么就把相应的代码块提交给svn上。

单元测试的最基本的一个功能是能进行自动化测试。单元测试都是通过断言的方式来确定结果是否正确,即使用Assert。

Maven中pom.xml添加的依赖文件可以在http://mvnrepository.com/search?q=中查找

运用Maven管理下载包,在POM中添加:

 1 <dependencies>
 2         <dependency>
 3             <groupId>junit</groupId>
 4             <artifactId>junit</artifactId>
 5             <version>4.12</version>
 6             <scope>test</scope>
 7         </dependency>
 8 
 9         <dependency>
10             <groupId>org.hamcrest</groupId>
11             <artifactId>hamcrest-library</artifactId>
12             <version>1.3</version>
13             <scope>test</scope>
14         </dependency>
15     </dependencies>

新建一个类Calcuate,其功能主要实现加减乘除

 1 public class Calcuate {
 2 
 3     /**
 4      * description:加法运算
 5      * @param a
 6      * @param b
 7      * @return a+b
 8      */
 9     public int add(int a, int b) {
10         return a + b;
11     }
12 
13     /**
14      * description:减法运算
15      * @param a
16      * @param b
17      * @return a-b
18      */
19     public int minus(int a, int b) {
20         return a - b;
21     }
22 
23     /**
24      * description:除法运算
25      * @param a
26      * @param b
27      * @return a/b
28      */
29     public int divide(int a, int b) {
30         return a / b;
31     }
32 
33     /**
34      * description:乘法运算
35      * @param a
36      * @param b
37      * @return
38      */
39     public int mul(int a, int b) {
40         return a * b;
41     }

选中测试包,右键-》新建Junit Test Case ;

junit3与junit4的区别还是比较明显的,在junit3中,如果某个类是测试类,必须将其继承类TestCase,如果某个方法是测试方法,必须让这个方法以testXX开头,如果希望指定某个测试方法运行之前运行某个初始化方法,这个方法的名称必须是setUp,如果希望在某个测试方法运行之后运行某个释放资源的方法,这个方法的名称必须是tearDown。

在junit4中,一个POJO类就是一个测试类,测试方法通过@Test来标识,初始化方法通过@Before来标识,释放资源的方法通过@After来标识,但是为了让junit4的测试类在junit3中也可以使用,习惯于把初始化方法命名为setUp,释放资源的方法命名为tearDown。Test中的测试方法一般以Test来开始。其中标识为Before注解的方法,每次运行测试类,都会执行标识为@After与@Before的方法。

 1 public class TestCalcuate {
 2 
 3     Calcuate cal;
 4     
 5     @Before
 6     public void setUp() throws Exception {
 7         cal = new Calcuate();
 8     }
 9 
10     
11     @After
12     public void tearDown() throws Exception {
13     }
14 
15     @Test
16     public void testAdd() {
17         int rel = cal.add(1, 2);
18         Assert.assertEquals("加法有问题", rel, 3);
19     }
20     
21     @Test
22     public void testMinus(){
23         int rel = cal.minus(3, 1);
24         Assert.assertEquals("减法有问题", rel,2);
25     }
26     
27     @Test
28     public void testDivide(){
29         int rel = cal.divide(10, 1);
30         Assert.assertEquals("除法有问题", rel, 9);
31     }

在junit4中提供了一个Assert的类,这个类中有大量的静态方法进行断言的处理,在junit3中由于继承了TestCase,这个TestCase就可以直接assert,而junit4中需要先引入Assert类。

在上图中使用了Assert类中的assertEquals方法,这方法的第一个参数意思是:如果方法cal.Add(1,2)计算的结果不为3,那么就会打印出“加法有问题”的信息。第二个参数为方法cal.Add(1,2)的执行结果,第三个参数是开发人员预计的函数cal.Add(1,2)执行后的结果。

使用junit测试比使用main方法测试有很大的不同的,每个标识为@Test的方法都是一个可运行的方法,并且他们之间互不影响,例如testAddd方法出现问题了,并不影响testMinus方法的运行,这就是单元测试的好处。技术分享

在测试除法cal.divide(10,0),如果除数为0,这个方法应该会抛出异常。现在的测试目标是,如果运行测试方法,测试方法没有抛出异常,那么这个测试方法就不能通过。这时就需要用到junit的ArithmeticException。

技术分享

这里如果把cal.divide(10,0)改成cal.divide(10,1),这样divide是没有问题的,但是这时测试类中的testDivideException方法执行junit测试后就不能通过了,因为这个测试方法已经断言所要测试的方法divide要抛出异常,结果没有抛出异常,所以junit测试是不能通过的。

技术分享

Junit的最基本的东西是这样的,断言、测试异常,捕获异常,测试方法的性能。

hamcrest

很多时候使用assert做判断,并不方便,如果要判断某几个值是否为true或false,这时使用hamcrest来判断就会方便许多。hamcrest就是专门为增强junit来提供的框架。

如果出现以下错误:

技术分享

其原因是因为资源路径里junit的jar包在hamcrest的jar包上面,java运行环境先从junit包中查找allOf方法,但是这里使用的是hamcrest的allOf方法。从资源路径里把两个包的路径换一下就可以了。如下图,选择hamcrest的jar包点击up,就可以反hamcrest的jar包放在junit的jar包的上面,java运行环境就会优先从hamcrest包中查allOf方法。

技术分享

TestSuite

在一个项目中,可能有很多的测试类,如果每个测试类都要点击运行,那么成百上千个类都需要测试,这会是个比较繁重的工作,这时可以使用可以使用junit的jar包中提供的Suite来解决这个问题,上面的例子中只有一个测试类名叫TestCalcuate,现在新建两个测试类,分别为testA、testB

然后新建一个测试类TestSuite,这个类可以把以上三个类,testCalcuate、testA、testB,这三个测试方法同事进行测试。

@RunWith(Suite.class)      //代表以Suite来运行这个测试类
@SuiteClasses({testA.class,testB.class,testCalcuate.class})     //代表要测试的类有哪些

技术分享

注意:

1.建议创建一个专门的source folder--->test来编写测试类代码。

2.测试类的包应该保持和需要测试的类一致。

3.测试单元中的每个测试方法都必须可以独立执行,不相互依赖。

 

以上是关于单元测试的主要内容,如果未能解决你的问题,请参考以下文章

为什么使用Junit单元测试?Junit的详解

为什么使用Junit单元测试?Junit的详解

junit-单元测试

Java单元测试工具:JUnit4

JUnit单元测试

单元测试Junit