Junit使用详解
http://junit.org/上详细介绍了Junit。JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.(Junit是一个可用于编写可复用测试集的简单框架,是xUnit的一个子集,而xUnit是一个基于测试驱动开发的测试框架(例如面向python的PythonUnit、面向C++的CppUnit和面向Java的单元测试框架Junit)),Junit的源代码托管在了github上https://github.com/junit-team/junit。java doc地址:http://junit.org/javadoc/latest/index.html
这个页面提供了快速上手的示例https://github.com/junit-team/junit/wiki/Getting-started。
Junit使用断言机制将程序的运行结果和我们预期的结果进行比对。
快速上手
由于Eclipse中集成了Junit4,所以我们不需要单独下载jar包。
首先,建立一个被用于测试的类:
package org.gpf.util;
/**
* 被测试的类
* 包含+、-、*、/的4个方法
*/
public class Calculate { public int add(int num1,int num2){
return num1 + num2;
} public int sub(int num1,int num2){
return num1 - num2;
} public int mul(int num1,int num2){
return num1 * num2;
} public int div(int num1,int num2){
return num1 / num2;
}
}
然后,导入Junit4的jar包。在项目中单击右键--->BuildPath--->Add Libraries--->Juint.
接下来,在当前包中新建一个测试用例。在被测试类所在的包中右键--->新建--->Juint Test Case。如下图所示
Eclipse会自动为我们生成模板:
package org.gpf.util; import static org.junit.Assert.*; import org.junit.Test; public class CalculateTest { @Test
public void test() {
fail("Not yet implemented");
} }
接下来仿照以上的模板,测试自己的方法:
package org.gpf.util; import static org.junit.Assert.*; import org.junit.Test; public class CalculateTest { @Test
public void testAdd(){
assertEquals(9, new Calculate().add(3, 6)); // 断言3+6 = 9
}
}
最后,运行测试用例(Run As Junit Test)
Junit使用详解
在以上的简单上手的示例中将程序的源代码和测试代码放在同一目录下,这样就比较混乱。一个最佳实践就是在项目下新建一个test源代码目录,在test目录下新建新建测试用例,当产品测试完成上线之后删除test目录即可。
package org.gpf.util; import static org.junit.Assert.*; import org.junit.Test; public class CalculateTest { @Test
public void testAdd(){
assertEquals(9, new Calculate().add(3, 6)); // 断言3+6 = 9
} @Test
public void testSub(){
assertEquals(0, new Calculate().sub(3, 6));// 断言3-6 =0
} @Test
public void testMul(){
assertEquals(18, new Calculate().mul(3, 6));// 断言3*6 = 18
} @Test
public void testDiv(){
assertEquals(9, new Calculate().div(3, 6)); // 断言3/6 = 9
}
}
在Eclipse中右键Run As Junit Test,将会测试所有的方法。如果只需要测试特定的方法只需要在包视图中选定特定的方法,运行Junit测试即可。
总结:
- 测试方法必须使用@Test注解;
- 测试方法必须使用public void进行修饰,不能带任何的参数;
- 新建源代码目录来存放我们的测试代码;
- 测试类的包应该和被测试类保持一致;
- 测试单元中的每个方法必须可以独立测试,测试方法见不能存在任何的依赖;
- 测试类推荐使用Test最为类名的后缀;
- 测试方法推荐使用test作为方法名的前缀。
测试失败的2种情况
“测试用例不是用来证明你是对的,而是用来证明你没有错。”——测试用例用来表达预期结果,但对于逻辑错误却无能为力。
新建一个测试用例,命名为ErrorAndFailureTest,测试add方法:
public class ErrorAndFailureTest { @Test
public void testAdd(){
assertEquals(10, new Calculate().add(3, 6)); // 断言3+6 = 10
} }
运行此测试用例:
现在注释掉testAdd测试方法,加入testDiv测试方法,在testDiv方法中我们断言3/0=9.
public class ErrorAndFailureTest { @Test
public void testDiv(){
assertEquals(9, new Calculate().div(3, 0)); // 断言3/0 = 9
}
}
运行此测试用例,
小结:
- Failure一般是由单元测试使用的断言方法判断失败所引起的,表名测试点发现了问题,就是说程序的输出结果和我们预期的不一样。
- Error是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中的一个隐藏的bug;
- 测试用例不是用来证明你是对的,而是用来证明你没有错。
Junit的运行流程
打开开发工具,新建一个Junit Test Case,选中4个方法:
我们在它自动生成的4个方法中各打印一句话,同时加入两个我们自己的测试方法:
package org.gpf.util; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; public class JunitFlowTest { @BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("这是BeforeClass---静态方法");
} @AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("这是AfterClass---静态方法");
} @Before
public void setUp() throws Exception {
System.out.println("这是Before");
} @After
public void tearDown() throws Exception {
System.out.println("这是After");
} @Test
public void test1(){
System.out.println("这是test1");
} @Test
public void test2(){
System.out.println("这是test2");
}
}
小结
- @BeforeClass修饰的方法会在所有的方法被调用前执行,而且该方法是静态的,所以当测试类被加载后会接着运行它,在内存中只存在一份实例。比较适合加载一些配置文件。
- @AfterClass所修饰的方法通常用来对资源的清理。例如:关闭DB连接。
- @Before和@After会在每个测试方法的前后各执行一次。
- @BeforeClass和@AfterClass是固定代码,一定会被执行到。
Junit的常用注解
注解 | 说明 |
@Test | 将一个普通的方法修饰成为测试方法。(expected=XX.class,用于预期捕获某种异常,使其通过测试;timeout=毫秒,用于对方法的运行时间进行限定,防止死循环和进行性能测试) |
@BeforeClass | 在所有的方法运行前被执行,static修饰 |
@afterClass | 在所有的方法运行后被执行,static修饰 |
@Before | 每个测试方法运行前执行 |
@After | 每个测试方法运行后执行 |
@Ignore | 所修饰的方法会被测试运行器忽略 |
@RunWith | 可以更改测试运行器,自定义自己的运行器需要继承org.junit.runner.Runner抽象类。但是一般情况下使用默认的测试运行器即可 |
public class AnnotationTest { @Test(expected=ArithmeticException.class)
public void testDiv(){
assertEquals(9, new Calculate().div(3, 0)); // 断言3/0 = 9
} }
在以上的程序中我们断言3/0 = 9,运行Junit本身应该是红色,但是运行以上程序,发现Junit的状态条变成了绿色,测试竟然通过了!
/**
* 防止出现死循环
*/
@Test(timeout=3000)
public void testWhile(){
while (true) {
System.out.println("此段代码永远运行!");
}
} /**
* 性能测试:读取文件的操作必须在3s内完成
*/
@Test(timeout=3000)
public void testReadFile(){
try {
Thread.sleep(2000); // 模拟读文件需要2s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
加入@Ignore注解的方法会被测试运行器忽略:
public class AnnotationTest { @Test(expected=ArithmeticException.class)
public void testDiv(){
assertEquals(9, new Calculate().div(3, 0)); // 断言3/0 = 9
} /**
* 防止出现死循环,加上@Ignore后会被测试运行器忽略
*/
@Ignore("该方法被测试忽略")
@Test(timeout=3000)
public void testWhile(){
while (true) {
System.out.println("此段代码永远运行!");
}
} /**
* 性能测试:读取文件的操作必须在2s内完成
*/
@Test(timeout=3000)
public void testReadFile(){
try {
Thread.sleep(2000); // 模拟读文件需要2s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Junit深入使用
测试套件的使用
使用测试套件可以将多个测试类集成到一个测试套件中,这样需要验证系统功能的时候只需要执行一次测试套件即可。需要将多个测试类集成到一个测试套件中只需要在测试所在的包上右键--->New--->Junit--->JunitTestCase即可。
package org.gpf.util; import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class)
@SuiteClasses({ AnnotationTest.class, CalculateTest.class,
ErrorAndFailureTest.class, JunitFlowTest.class })
public class AllTests { }
测试套件中可以包含其他的测试套件,直接像包含测试类那样在@SuiteClasses中加入测试套件的类名即可。
编写一个测试套件的步骤:
- 写一个作为测试套件的入口类,这个类中不包含其他的方法;
- 更改测试运行器(@RunWith())为Suite.class;
- 将测试类作为数组传递到@SuiteClasses({})中。
Junit参数化设置
对于相同的测试方法,例如加法操作,如果我们要进行多组数据的加法操作,就需要写多个测试加法的方法。代码结构都是相同的,不同的仅仅是测试的数据和预期值。Junit4可以通过参数化配置提高代码的可重用度。
import static org.junit.Assert.*; import java.util.Arrays;
import java.util.Collection; import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class)
public class ParameterTest { int expected = 0;
int input1 = 0;
int input2 = 0; @Parameters
public static Collection<Object[]> t(){ return Arrays.asList(new Object[][]{
{3,1,2},
{4,2,2},
{9,3,3}
});
} /**
* 提供一个构造方法,初始化预期值和2个输入数据
* @param expected 预期值
* @param input1 输入参数1
* @param input2 输入参数2
*/
public ParameterTest(int expected,int input1,int input2) {
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
} @Test
public void addTest(){
assertEquals(expected, new Calculate().add(input1, input2)); // 该测试方法将对3组测试用例进行测试
}
}
配置参数化测试的步骤:
- 更改默认的测试运行器为@RunWith(Parameterized.class);
- 声明变量来存放预期值和输入参数;
- 声明一个返回值为Collection的公共静态方法,并使用@Parameters注解修饰;
- 为测试类声明一个带有参数的公共构造方法,在构造方法中为声明变量赋值。
使用Junit整合Spring和Hibernate
待续。。。。。
Junit使用详解的更多相关文章
- junit 常用注解 + junit 断言详解
@Test: 在junit3中,是通过对测试类和测试方法的命名来确定是否是测试,且所有的测试类必须继承junit的测试基类.在junit4中,定义一个测试方法变得简单很多,只需要在方法前加上@Test ...
- 单元测试junit框架详解
首先在给出一个类Operator,加入如下代码: public class Operator { // 加法 运算 public int add(int i,int j){ return i+j; } ...
- 详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)(下)
在上一篇(详解intellij idea 搭建SSM框架(spring+maven+mybatis+mysql+junit)(上))博文中已经介绍了关于SSM框架的各种基础配置,(对于SSM配置不熟悉 ...
- [原创]mybatis详解说明
mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...
- (十)Maven依赖详解
1.何为依赖? 比如你是个男的,你要生孩子,呸呸呸...男的怎么生孩子,所以你得依赖你老婆,不过也不一定咯,你也可以依赖其她妹子. 我们在平时的项目开发中也是同理,你需要依赖一些东西才能实现相应的功能 ...
- Myeclipse Templates详解(一) —— Java模板基础
目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...
- Spring jar包详解
Spring jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spri ...
- Spring——jar包详解(转)
Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spr ...
- Spring 3.x jar 包详解 与 依赖关系
以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...
随机推荐
- windows系统中常用的快捷键
开发中,一些常用的键盘技巧: (1)快速切换桌面(alt+tab)或者是(window+tab) (2)迅速关闭当前页面 (3)迅速收起所有页面 (4)直接回到桌面页面 (5)锁定你的屏幕
- iOS开发-使用storyboard实现UILabel的自适应高度(iOS8)
好久没有写博客了.以后多写些博客,对自己是一种提升.对大家也是一种帮助 近期特别痴迷storyboard和xib的可视化编程,在写项目的时候遇到个问题就是怎样使UILabel自适应高度,查了好多文章博 ...
- SVN 常见命令
一.什么是SVN SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. 二.SVN的下载安装 下载地址:http ...
- Docker Container同时启动多服务 supervisor
Docker Container同时启动多服务 转载请注明来自:http://blog.csdn.net/wsscy2004 昨天踩了个天坑,我有一个基本的镜像centos6.5+ssh,是通过Doc ...
- DevOps,不是一个传说!
转自: http://www.infoq.com/cn/articles/devops-not-legend DevOps最近成了热词,望文生义,你也能猜个八九不离十,它就是在说"研发团队& ...
- iOS CoreData (一) 增删改查
代码地址如下:http://www.demodashi.com/demo/11041.html Core Data是iOS5之后才出现的一个框架,本质上是对SQLite的一个封装,它提供了对象-关系映 ...
- iDempiere VS ADempiere
怀揣着为中小企业量身定做一整套开源软件解决方案的梦想开始了一个网站的搭建.http://osssme.org/ 第三篇:iDempiere VS ADempiere 一直以来,什么谁谁谁VS谁谁谁的, ...
- NOPcommerce研究
http://www.cnblogs.com/gusixing/archive/2012/04/07/2435873.html
- 静态资源打包:一个javescript 的src引用多个文件,一个link引用多个CSS文件
疑惑描述: 查看了淘宝网的首页源文件,看到这样的一个特殊的 <script src="http://a.tbcdn.cn/??s/kissy/1.1.6/kissy-min.js,p/ ...
- redis命令_ZREVRANGEBYSCORE
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 返回有序集 key 中, score 值介于 max 和 min 之间(默 ...