文档章节

Junit使用教程

乐在克里特
 乐在克里特
发布于 2017/02/23 14:54
字数 2394
阅读 7
收藏 0
点赞 0
评论 0

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

测试一般分为:单元测试、集成测试(主要看一块代码加进去后,系统会不会有问题)、验收测试和压力测试。

 

       在以前的的项目中也用过Junit,当时的使用只是把Junit当成一个有多个main方法的一个函数。假如一个项目非常的大,测试的东西非常的多,如果不用Junit的话,那么这个工作量是非常大的。单元测试的最基本的一个功能是能进行自动化测试。单元测试都是通过断言的方式来确定结果是否正确,即使用Assert。

 

一、建立Junit测试类

1. 右击test测试包,选择New-->Oher...

 

2. 在窗口中找到Junit,选择Junit Test Case

3. 输入名称(Name),命名规则一般建议采用:类名+Test。Browse...选择要测试的类,这里是StudentService。

4. 勾选要测试的方法

5. 生成后,效果如下:

这里import static是引入Assert类中静态属性或静态方法的写法。原来要Assert.fail(),现在只需直接fial()即可,即省略了Assert。

其实不通过Junit新建向导来建立也可以,随便建立一个新类后,只需在方法上加入@Test注解即可。

 

二、核心——断言

断言是编写测试用例的核心实现方式,即期望值是多少,测试的结果是多少,以此来判断测试是否通过。

1. 断言核心方法

assertArrayEquals(expecteds, actuals) 查看两个数组是否相等。
assertEquals(expected, actual) 查看两个对象是否相等。类似于字符串比较使用的equals()方法
assertNotEquals(first, second) 查看两个对象是否不相等。
assertNull(object) 查看对象是否为空。
assertNotNull(object) 查看对象是否不为空。
assertSame(expected, actual) 查看两个对象的引用是否相等。类似于使用“==”比较两个对象
assertNotSame(unexpected, actual) 查看两个对象的引用是否不相等。类似于使用“!=”比较两个对象
assertTrue(condition) 查看运行结果是否为true。
assertFalse(condition) 查看运行结果是否为false。
assertThat(actual, matcher) 查看实际值是否满足指定的条件
fail() 让测试失败

2. 示例

[java]   view plain
  1. package test;  
  2.   
  3. import static org.hamcrest.CoreMatchers.*;  
  4. import static org.junit.Assert.*;  
  5.   
  6. import java.util.Arrays;  
  7.   
  8. import org.hamcrest.core.CombinableMatcher;  
  9. import org.junit.Test;  
  10.   
  11. public class AssertTests {  
  12.   
  13.       @Test   
  14.       public void testAssertArrayEquals() {  
  15.         byte[] expected = "trial".getBytes();  
  16.         byte[] actual = "trial".getBytes();  
  17.         org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);  
  18.       }  
  19.   
  20.       @Test   
  21.       public void testAssertEquals() {  
  22.         org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);  
  23.       }  
  24.   
  25.       @Test   
  26.       public void testAssertFalse() {  
  27.         org.junit.Assert.assertFalse("failure - should be false"false);  
  28.       }  
  29.   
  30.       @Test   
  31.       public void testAssertNotNull() {  
  32.         org.junit.Assert.assertNotNull("should not be null"new Object());  
  33.       }  
  34.   
  35.       @Test  
  36.       public void testAssertNotSame() {  
  37.         org.junit.Assert.assertNotSame("should not be same Object"new Object(), new Object());  
  38.       }  
  39.   
  40.       @Test  
  41.       public void testAssertNull() {  
  42.         org.junit.Assert.assertNull("should be null"null);  
  43.       }  
  44.   
  45.       @Test  
  46.       public void testAssertSame() {  
  47.         Integer aNumber = Integer.valueOf(768);  
  48.         org.junit.Assert.assertSame("should be same", aNumber, aNumber);  
  49.       }  
  50.   
  51.       // JUnit Matchers assertThat  
  52.       @Test  
  53.       public void testAssertThatBothContainsString() {  
  54.         org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));  
  55.       }  
  56.   
  57.       @Test  
  58.       public void testAssertThathasItemsContainsString() {  
  59.         org.junit.Assert.assertThat(Arrays.asList("one""two""three"), hasItems("one""three"));  
  60.       }  
  61.   
  62.       @Test  
  63.       public void testAssertThatEveryItemContainsString() {  
  64.         org.junit.Assert.assertThat(Arrays.asList(new String[] { "fun""ban""net" }), everyItem(containsString("n")));  
  65.       }  
  66.   
  67.       // Core Hamcrest Matchers with assertThat  
  68.       @Test  
  69.       public void testAssertThatHamcrestCoreMatchers() {  
  70.         assertThat("good", allOf(equalTo("good"), startsWith("good")));  
  71.         assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));  
  72.         assertThat("good", anyOf(equalTo("bad"), equalTo("good")));  
  73.         assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));  
  74.         assertThat(new Object(), not(sameInstance(new Object())));  
  75.       }  
  76. }  

三、核心——注解

1. 说明

@Before 初始化方法
@After 释放资源
@Test 测试方法,在这里可以测试期望异常和超时时间
@Ignore 忽略的测试方法
@BeforeClass 针对所有测试,只执行一次,且必须为static void
@AfterClass 针对所有测试,只执行一次,且必须为static void
@RunWith 指定测试类使用某个运行器
@Parameters 指定测试类的测试数据集合
@Rule 允许灵活添加或重新定义测试类中的每个测试方法的行为
@FixMethodOrder 指定测试方法的执行顺序

2. 执行顺序

一个测试类单元测试的执行顺序为:

@BeforeClass –> @Before –> @Test –> @After –> @AfterClass

每一个测试方法的调用顺序为:

@Before –> @Test –> @After

3. 示例

[java]   view plain
  1. package test;  
  2.   
  3. import static org.junit.Assert.*;  
  4.   
  5. import org.junit.*;  
  6.   
  7. public class JDemoTest {  
  8.   
  9.     @BeforeClass  
  10.     public static void setUpBeforeClass() throws Exception {  
  11.         System.out.println("in BeforeClass================");  
  12.     }  
  13.   
  14.     @AfterClass  
  15.     public static void tearDownAfterClass() throws Exception {  
  16.         System.out.println("in AfterClass=================");  
  17.     }  
  18.   
  19.     @Before  
  20.     public void before() {  
  21.         System.out.println("in Before");  
  22.     }  
  23.   
  24.     @After  
  25.     public void after() {  
  26.         System.out.println("in After");  
  27.     }  
  28.   
  29.     @Test(timeout = 10000)  
  30.     public void testadd() {  
  31.         JDemo a = new JDemo();  
  32.         assertEquals(6, a.add(33));  
  33.         System.out.println("in Test ----Add");  
  34.     }  
  35.   
  36.     @Test  
  37.     public void testdivision() {  
  38.         JDemo a = new JDemo();  
  39.         assertEquals(3, a.division(62));  
  40.         System.out.println("in Test ----Division");  
  41.     }  
  42.   
  43.     @Ignore  
  44.     @Test  
  45.     public void test_ignore() {  
  46.         JDemo a = new JDemo();  
  47.         assertEquals(6, a.add(15));  
  48.         System.out.println("in test_ignore");  
  49.     }  
  50.   
  51.     @Test  
  52.     public void teest_fail() {  
  53.         fail();  
  54.     }  
  55. }  
  56.   
  57. class JDemo extends Thread {  
  58.   
  59.     int result;  
  60.   
  61.     public int add(int a, int b) {  
  62.         try {  
  63.             sleep(1000);  
  64.             result = a + b;  
  65.         } catch (InterruptedException e) {  
  66.         }  
  67.         return result;  
  68.     }  
  69.   
  70.     public int division(int a, int b) {  
  71.         return result = a / b;  
  72.     }  
  73. }  

执行结果:

[plain]   view plain
  1. in BeforeClass================  
  2. in Before  
  3. in Test ----Add  
  4. in After  
  5. in Before  
  6. in Test ----Division  
  7. in After  
  8. in AfterClass=================  

 

图中左上红框中部分表示Junit运行结果,5个成功(1个忽略),1个错误,1个失败。(注意错误和失败不是一回事,错误说明代码有错误,而失败表示该测试方法测试失败)

左下红框中则表示出了各个测试方法的运行状态,可以看到成功、错误、失败、失败各自的图标是不一样的,还可以看到运行时间。

右边部分则是异常堆栈,可查看异常信息。

 

四、实例总结

1. 参数化测试

有时一个测试方法,不同的参数值会产生不同的结果,那么我们为了测试全面,会把多个参数值都写出来并一一断言测试,这样有时难免费时费力,这是我们便可以采用参数化测试来解决这个问题。参数化测试就好比把一个“输入值,期望值”的集合传入给测试方法,达到一次性测试的目的。

[java]   view plain
  1. package test;  
  2.   
  3. import static org.junit.Assert.*;  
  4.   
  5. import java.util.Arrays;  
  6.   
  7. import org.junit.Test;  
  8. import org.junit.runner.RunWith;  
  9. import org.junit.runners.Parameterized;  
  10. import org.junit.runners.Parameterized.Parameters;  
  11.   
  12. @RunWith(Parameterized.class)  
  13. public class FibonacciTest {  
  14.   
  15.     @Parameters(name = "{index}: fib({0})={1}")  
  16.     public static Iterable<Object[]> data() {  
  17.         return Arrays.asList(new Object[][] { { 00 }, { 11 }, { 21 },  
  18.                 { 32 }, { 43 }, { 55 }, { 68 } });  
  19.     }  
  20.   
  21.     private int input;  
  22.     private int expected;  
  23.   
  24.     public FibonacciTest(int input, int expected) {  
  25.         this.input = input;  
  26.         this.expected = expected;  
  27.     }  
  28.   
  29.     @Test  
  30.     public void test() {  
  31.         assertEquals(expected, Fibonacci.compute(input));  
  32.     }  
  33. }  
  34.   
  35. class Fibonacci {  
  36.   
  37.     public static int compute(int input) {  
  38.         int result;  
  39.         switch (input) {  
  40.         case 0:  
  41.             result = 0;  
  42.             break;  
  43.         case 1:  
  44.         case 2:  
  45.             result = 1;  
  46.             break;  
  47.         case 3:  
  48.             result = 2;  
  49.             break;  
  50.         case 4:  
  51.             result = 3;  
  52.             break;  
  53.         case 5:  
  54.             result = 5;  
  55.             break;  
  56.         case 6:  
  57.             result = 8;  
  58.             break;  
  59.         default:  
  60.             result = 0;  
  61.         }  
  62.         return result;  
  63.     }  
  64. }  

@Parameters注解参数name,实际是测试方法名称。由于一个test()方法就完成了所有测试,那假如某一组测试数据有问题,那在Junit的结果页面里该如何呈现?因此采用name实际上就是区分每个测试数据的测试方法名。如下图:

2. 打包测试

同样,如果一个项目中有很多个测试用例,如果一个个测试也很麻烦,因此打包测试就是一次性测试完成包中含有的所有测试用例。

[java]   view plain
  1. package test;  
  2.   
  3. import org.junit.runner.RunWith;  
  4. import org.junit.runners.Suite;  
  5.   
  6. @RunWith(Suite.class)  
  7. @Suite.SuiteClasses({ AssertTests.class, FibonacciTest.class, JDemoTest.class })  
  8. public class AllCaseTest {  
  9.   
  10. }  

这个功能也需要使用一个特殊的Runner ,需要向@RunWith注解传递一个参数Suite.class 。同时,我们还需要另外一个注解@Suite.SuiteClasses,来表明这个类是一个打包测试类。并将需要打包的类作为参数传递给该注解就可以了。至于AllCaseTest随便起一个类名,内容为空既可。运行AllCaseTest类即可完成打包测试

3. 异常测试

异常测试与普通断言测试不同,共有三种方法,其中最为灵活的是第三种,可以与断言结合使用

第一种:

[java]   view plain
  1. @Test(expected= IndexOutOfBoundsException.class)   
  2. public void empty() {   
  3.      new ArrayList<Object>().get(0);   
  4. }  

第二种:

[java]   view plain
  1. @Test  
  2. public void testExceptionMessage() {  
  3.     try {  
  4.         new ArrayList<Object>().get(0);  
  5.         fail("Expected an IndexOutOfBoundsException to be thrown");  
  6.     } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {  
  7.         assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));  
  8.     }  
  9. }  

第三种:

[java]   view plain
  1. @Rule  
  2. public ExpectedException thrown = ExpectedException.none();  
  3.   
  4. @Test  
  5. public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {  
  6.     List<Object> list = new ArrayList<Object>();  
  7.   
  8.     thrown.expect(IndexOutOfBoundsException.class);  
  9.     thrown.expectMessage("Index: 0, Size: 0");  
  10.     list.get(0);  
  11.     Assert.assertEquals(1, list.get(0));  
  12. }  

在上述几种方法中,无论是expected还是expect都表示期望抛出的异常,假如某一方法,当参数为某一值时会抛出异常,那么使用第一种方法就必须为该参数单独写一个测试方法来测试异常,而无法与其他参数值一同写在一个测试方法里,所以显得累赘。第二种方法虽然解决这个问题,但是写法不仅繁琐也不利于理解。而第三种犯法,不仅能动态更改期望抛出的异常,与断言语句结合的也非常好,因此推荐使用该方法来测试异常。

4. 限时测试

有时为了防止出现死循环或者方法执行过长(或检查方法效率),而需要使用到限时测试。顾名思义,就是超出设定时间即视为测试失败。共有两种写法。

第一种:

[java]   view plain
  1. @Test(timeout=1000)  
  2. public void testWithTimeout() {  
  3.   ...  
  4. }  

第二种:

[java]   view plain
  1. public class HasGlobalTimeout {  
  2.     public static String log;  
  3.   
  4.     @Rule  
  5.     public Timeout globalTimeout = new Timeout(10000); // 10 seconds max per method tested  
  6.   
  7.     @Test  
  8.     public void testInfiniteLoop1() {  
  9.         log += "ran1";  
  10.         for (;;) {  
  11.         }  
  12.     }  
  13.   
  14.     @Test  
  15.     public void testInfiniteLoop2() {  
  16.         log += "ran2";  
  17.         for (;;) {  
  18.         }  
  19.     }  
  20. }  

其中,第二种方法与异常测试的第三种方法的写法类似。也是推荐的写法。

 

http://huihai.iteye.com/blog/1986568

http://blog.csdn.net/wangpeng047/article/details/9627527

 

 

© 著作权归作者所有

共有 人打赏支持
乐在克里特
粉丝 15
博文 268
码字总数 394729
作品 0
杭州
程序员
在 NetBeans IDE 中编写 JUnit 测试

测试应用程序是开发周期中不可缺少的一部分,并且编写和维护测试单元有利于确保源代码中的方法能正常运行。IDE 集成了对 JUnit 单元测试框架的支持,它允许您快速和轻松地创建 JUnit 测试和测...

刘学炜
2011/12/26
0
0
JUnit 5.2.0 发布,Java 单元测试框架

JUnit 5.2.0 发布,JUnit 5.2.0 = Platform 1.2.0 + Jupiter 5.2.0 + Vintage 5.2.0,此次更新包括构建工具的增强、参数化测试的改进等。 更新信息如下: 构建工具功能增强以支持新的模块化体...

雨田桑
05/04
0
0
Android、JUnit深入浅出(一)——JUnit初步解析

Android、JUnit深入浅出(一)——JUnit初步解析 Android SDK 1.5已经将JUnit包含进来了,但是一直没有去深入了解,以前在使用一些C++的开源库中学习过与CPPUnit,简要分析过其主要框架,如下...

庸人谷
2012/12/26
0
0
Junit的新长征-Junit5

这几天做新课时,忽然发现Junit在Junit4这个版本上停留了十几年之后,原来已经出到5了(后知后觉),花了些时间研究了下,发现还真是不简单,我们一起来看看JUnit5上出现了哪些让人激动的新变...

城下秋草
07/17
0
0
Java Web(5) Spring 下使用Junit4 单元测试

如何在不启动Tomcat服务器的情况下对,Dao这些不依赖使用Servlet API的类来进行单元测试呢? 其实在Spring框架体系中,已经有一套自己的测试代码,其中就是依赖使用Junit来进行测试 ,不需要...

Jagery
2015/11/15
0
0
springboot在jetty+websocket的环境下的junit测试失败

这个问题描述起来可能还比较长。 首先我在springboot中选择了jetty作为服务器,然后现在我希望使用jetty的websocket功能,因此边加了jetty的websocket包。按照网上的教程,只要注意把tomcat的...

kuma_ller
05/27
0
0
Ant和Junit使用的一些问题

ant集成junit自动测试的build.xml标准模板 利用Ant集成Junit自动测试并生成测试报告,可以极大的提高测试的工作效率,其优势只要是测试用例的批量处理功能。前不久在网上看到很多关于Junit测...

墙头草
2012/01/06
0
0
JMockit+JUnit单元测试初始化问题

一、项目环境: WIN7 64位,Eclipse 4.2,JDK1.6,JUnit 4.11,JMockit 1.10 二、示例代码: 使用JUnit + JMockit进行单元测试,运行JUnit Case时,抛出以下错误: java.lang.IllegalStateEx...

dexterman
2014/08/27
0
0
解决org/junit/Assume$AssumptionViolatedException异常

Spring版本2.5.5,JUnit 版本 4.8.1,使用了 Spring TestContext 的 SpringJUnit4ClassRunner。一直使用这个版本的JUnit,在写简单的测试时不会抛错,直到今天开始尝试写规范的JUnit测试代 ...

吕兵阳
2014/04/15
0
0
JUnit框架功能详细——JUnit学习(一)

是著名的单元测试框架,在JUnit4中所有的测试用例采用@Annotation标注,这比JUnit3的通过类继承和特定方法名带来更大的灵活性。在花了一周多的时间学习JUnit4使用及原码后发现自己以往只用到...

gangzz
2013/07/13
0
8

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql 主从复制中遇到的错误!

。。。。。

万建宁
13分钟前
0
0
DUBBO 详细介绍

摘要: 主要核心部件: Remoting: 网络通信框架,实现了 sync-over-async 和 request-response 消息机制. RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能 Registry: 服务目录框架...

明理萝
23分钟前
0
1
4 个快速的 Python 编译器 for 2018

简评:Python 和其他的解释型语言一样经常被吐槽性能不行,所以开发人员为了提升性能创建了不少编译器,本文则选取其中的四个做了基准测试。 Python 其实是一种相当快的语言,但它并不像编译...

极光推送
26分钟前
0
0
spring boot注册多个MQ服务器的问题

关于注册到多个MQ源的文章已经有很多了,这里记录一下声明queue的坑; 如果使用注册bean的方式声明queue,会导致声明的queue同时被注册到所有的MQ源上; //如果使用下面的声明方式,que...

placeholder
27分钟前
0
0
Java面试基础篇——第九篇:BIO,NIO,AIO的区别

现在IO模型主要分三类:BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO()。 先来看看BIO。 1. BIO 服务端接受到请求后,要指派或新建一个线程去处理客户端的IO请求,直到收到断开连接的指令。这么做...

developlee的潇洒人生
32分钟前
0
0
@RequestMapping @ResponseBody 和 @RequestBody 用法与区别

1.@RequestMapping 国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为...

特拉仔
34分钟前
1
0
基于 HTML5 结合互联网+ 的 3D 隧道

前言 目前,物资采购和人力成本是隧道业发展的两大瓶颈。比如依靠民间借贷,融资成本很高;采购价格不透明,没有增值税发票;还有项目管控和供应链管理的问题。成本在不断上升,利润在不断下...

xhload3d
36分钟前
0
0
济南小程序热度分析

原文链接:http://www.jnqianle.cn/company/2072.html

tianma3798
37分钟前
1
0
大数据软件

beats 采集 kafka spark hive es grafana zeppelin

ArlenXu
39分钟前
0
0
Mac item2常用快捷键

标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 command + 左右方向键 切换全屏:command + enter 查找:command + f 分屏 水平分屏:command + d 垂直分屏:c...

说回答
43分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部