JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。[1-2]   
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。

目录

1优点

2特性

3安装

4测试

5实践

6使用帮助

▪ junit3.x
▪ junit4.x
 
 

1优点编辑

另外junit是在极限编程和重构(refactor)中被极力推荐使用的工具,因为在实现自动单元测试的情况下可以大大的提高开发的效率,但是实际上编写测试代码也是需要耗费很多的时间和精力的,那么使用这个东东好处到底在哪里呢?笔者认为是这样的:
极限编程
要求在编写代码之前先写测试,这样可以强制你在写代码之前好好的思考代码(方法)的功能和逻辑,否则编写的代码很不稳定,那么你需要同时维护测试代码和实际代码,这个工作量就会大大增加。因此在极限编程中,基本过程是这样的:构思-> 编写测试代码-> 编写代码-> 测试,而且编写测试和编写代码都是增量式的,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。
重构
其好处和极限编程中是类似的,因为重构也是要求改一点测一点,减少回归错误造成的时间消耗。
其他情况
我们在开发的时候使用junit写一些适当的测试也是有必要的,因为一般我们也是需要编写测试的代码的,可能原来不是使用的junit,如果使用junit,而且针对接口(方法)编写测试代码会减少以后的维护工作,例如以后对方法内部的修改(这个就是相当于重构的工作了)。另外就是因为junit有断言功能,如果测试结果不通过会告诉我们哪个测试不通过,为什么,而如果是像以前的一般做法是写一些测试代码看其输出结果,然后再由自己来判断结果是否正确,使用junit的好处就是这个结果是否正确的判断是它来完成的,我们只需要看看它告诉我们结果是否正确就可以了,在一般情况下会大大提高效率。

2特性编辑

JUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例(用于java语言)。它包括以下特性:
1、用于测试期望结果的断言(Assertion)
2、用于共享共同测试数据的测试工具
3、用于方便的组织和运行测试的测试套件
4、图形和文本的测试运行器

3安装编辑

安装很简单,先到以下地址下载一个最新的zip包:
下载完以后解压缩到你喜欢的目录下,假设是JUNIT_HOME,然后将JUNIT_HOME下的junit.jar包加到你的系统的CLASSPATH环境变量中,对于IDE环境,对于需要用到的junit的项目增加到lib中,其设置不同的IDE有不同的设置,这里不多讲。

4测试编辑

最简单的范例如下:
1、创建一个TestCase的子类
package junitfaq;
import java.util.*;
import junit.framework.*;
public class SimpleTest extends TestCase {
public SimpleTest(String name) {
super(name);
}
2、写一个测试方法断言期望的结果
public void testEmptyCollection() {
Collection collection = new ArrayList();
assertTrue(collection.isEmpty());
}
注意:JUnit推荐的做法是以test作为待测试的方法的开头,这样这些方法可以被自动找到并被测试。
3、写一个suite()方法,它会使用反射动态的创建一个包含所有的testXxxx方法的测试套件
public static Test suite() {
return new TestSuite(SimpleTest.class);
}
4、写一个main()方法以文本运行器的方式方便的运行测试
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
}
5、运行测试
以文本方式运行:
java junitfaq.SimpleTest
通过的测试结果是:
.
Time: 0
OK (1 tests)
Time上的小点表示测试个数,如果测试通过则显示OK。否则在小点的后边标上F,表示该测试失败。
每次的测试结果都应该是OK的,这样才能说明测试是成功的,如果不成功就要马上根据提示信息进行修正了。
如果JUnit报告了测试没有成功,它会区分失败(failures)和错误(errors)。失败是你的代码中的assert方法失败引起的;而错误则是代码异常引起的,例如ArrayIndexOutOfBoundsException
以图形方式运行:
java junit.swingui.TestRunner junitfaq.SimpleTest
通过的测试结果在图形界面的绿色条部分。
以上是最简单的测试样例,在实际的测试中我们测试某个类的功能是常常需要执行一些共同的操作,完成以后需要销毁所占用的资源(例如网络连接、数据库连接,关闭打开的文件等),TestCase类给我们提供了setUp方法和tearDown方法,setUp方法的内容在测试你编写的TestCase子类的每个testXxxx方法之前都会运行,而tearDown方法的内容在每个testXxxx方法结束以后都会执行。这个既共享了初始化代码,又消除了各个测试代码之间可能产生的相互影响。

5实践编辑

不要认为压力大,就不写测试代码。相反编写测试代码会使你的压力逐渐减轻,因为通过编写测试代码,你对类的行为有了确切的认识。你会更快地编写出有效率地工作代码。
下面是一些具体的编写测试代码的技巧或较好的实践方法:
1. 不要用TestCase的构造函数初始化Fixture,而要用setUp()和tearDown()方法。
2. 不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。
3. 避免编写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,就不要提交交易数据。简单的回滚就可以了。
4. 当继承一个测试类时,记得调用父类的setUp()和tearDown()方法。
5. 将测试代码和工作代码放在一起,一边同步编译和更新。(使用Ant中有支持junit的task.)
6. 测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。
7. 确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
8. 如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。
9. 尽可能地利用JUnit提供地assert/fail方法以及异常处理的方法,可以使代码更为简洁。
10.测试要尽可能地小,执行速度快。
11.不要硬性规定数据文件的路径。
12.利用Junit 的自动异常处理书写简洁的测试代码
事实上在Junit 中使用try-catch 来捕获异常是没有必要的,Junit 会自动捕获异常。那些没有被捕获的异常就被当成错误处理。
13. 充分利用Junit 的assert/fail 方法
assertSame()用来测试两个引用是否指向同一个对象
assertEquals()用来测试两个对象是否相等
14. 确保测试代码与时间无关
15. 使用文档生成器做测试文档。
JUnit和ant结合
ant 提供了两个 target : junit 和 junitreport 运行所有测试用例,并生成 html 格式的报表
具体操作如下:
1.将 junit.jar 放在 ANT_HOMElib 目录下
2.修改 build.xml ,加入如下 内容:
-------------- One or more tests failed, check the report for detail... -----------------------------
运行 这个 target ,ant 会运行每个 TestCase,在 report 目录下就有了 很多 TEST*.xml 和 一些网页打开 report 目录下的 index.html 就可以看到很直观的测试运行报告,一目了然。
在Eclipse中开发、运行JUnit测试相当简单。因为Eclipse本身集成了JUnit相关组件,并对JUnit的运行提供了无缝的支持。

6使用帮助编辑

junit3.x

我们通常使用junit 3.8[3] 
(1)、使用junit3.x版本进行单元测试时,测试类必须要继承于TestCase父类;
(2)、测试方法需要遵循的原则:
A、public的
B、void的
C、无方法参数
D、方法名称必须以test开头
(3)、不同的Test Case之间一定要保持完全的独立性,不能有任何的关联。
(4)、我们要掌握好测试方法的顺序,不能依赖于测试方法自己的执行顺序。
demo:
public class TestMyNumber extends TestCase {
private MyNumber myNumber;
public TestMyNumber(String name) {
super(name);
}
// 在每个测试方法执行 [之前] 都会被调用
@Override
public void setUp() throws Exception {
// System.out.println("欢迎使用Junit进行单元测试…");
myNumber = new MyNumber();
}
// 在每个测试方法执行 [之后] 都会被调用
@Override
public void tearDown() throws Exception {
// System.out.println("Junit单元测试结束…");
}
public void testDivideByZero() {
Throwable te = null;
try {
myNumber.divide(6, 0);
Assert.fail("测试失败");
} catch (Exception e) {
e.printStackTrace();
te = e;
}
Assert.assertEquals(Exception.class, te.getClass());
Assert.assertEquals("除数不能为 0 ", te.getMessage());
}
}

junit4.x

(1)、使用junit4.x版本进行单元测试时,不用测试类继承TestCase父类,因为,junit4.x全面引入了Annotation来执行我们编写的测试。[3] 
(2)、junit4.x版本,引用了注解的方式,进行单元测试;
(3)、junit4.x版本我们常用的注解:
A、@Before 注解:与junit3.x中的setUp()方法功能一样,在每个测试方法之前执行;
B、@After 注解:与junit3.x中的tearDown()方法功能一样,在每个测试方法之后执行;
C、@BeforeClass 注解:在所有方法执行之前执行;
D、@AfterClass 注解:在所有方法执行之后执行;
E、@Test(timeout = xxx) 注解:设置当前测试方法在一定时间内运行完,否则返回错误;
F、@Test(expected = Exception.class) 注解:设置被测试的方法是否有异常抛出。抛出异常类型为:Exception.class;
G、@Ignore 注解:注释掉一个测试方法或一个类,被注释的方法或类,不会被执行。
demo:
package com.an.junit;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestMyNumber {
private MyNumber myNumber;
@BeforeClass
// 在所有方法执行之前执行
public static void globalInit() {
System.out.println("init all method...");
}
@AfterClass
// 在所有方法执行之后执行
public static void globalDestory() {
System.out.println("destory all method...");
}
@Before
// 在每个测试方法之前执行
public void setUp() {
System.out.println("start setUp method");
myNumber = new MyNumber();
}
@After
// 在每个测试方法之后执行
public void tearDown() {
System.out.println("end tearDown method");
}
@Test(timeout=600)// 设置限定测试方法的运行时间 如果超出则返回错误
public void testAdd() {
System.out.println("testAdd method");
int result = myNumber.add(2, 3);
assertEquals(5, result);
}
@Test
public void testSubtract() {
System.out.println("testSubtract method");
int result = myNumber.subtract(1, 2);
assertEquals(-1, result);
}
@Test
public void testMultiply() {
System.out.println("testMultiply method");
int result = myNumber.multiply(2, 3);
assertEquals(6, result);
}
@Test
public void testDivide() {
System.out.println("testDivide method");
int result = 0;
try {
result = myNumber.divide(6, 2);
} catch (Exception e) {
fail();
}
assertEquals(3, result);
}
@Test(expected = Exception.class)
public void testDivide2() throws Exception {
System.out.println("testDivide2 method");
myNumber.divide(6, 0);
fail("test Error");
}
public static void main(String[] args) {
}
}

认识Junit的更多相关文章

  1. 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file

    我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...

  2. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  3. AndroidStudio — Error:Failed to resolve: junit:junit:4.12错误解决

    原博客:http://blog.csdn.net/u013443865/article/details/50243193 最近使用AndroidStudio出现以下问题: 解决:打开app下的buil ...

  4. 「译」JUnit 5 系列:环境搭建

    原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...

  5. [深入JUnit] 测试运行的入口

    阅读前提 了解JUnit 对JUnit的内部实现有兴趣 不妨看看[深入JUnit] @Before, @After, @Test的秘密] 代码版本: junit 4.12代码搜索工具: http:// ...

  6. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  7. 「译」JUnit 5 系列:架构体系

    原文地址:http://blog.codefx.org/design/architecture/junit-5-architecture/ 原文日期:29, Mar, 2016 译文首发:Linesh ...

  8. 「译」JUnit 5 系列:基础入门

    原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...

  9. 新手入门JUnit单元测试

    首先将JUnit插件安装到Eclipse或myeclipse里面,编写完一个模块或者实体类的时候,直接右击,new一个JUnit项目,选择你想测试的实体类(模块),然后会自动生成一个类,这个类,我们将 ...

  10. [Android]使用自定义JUnit Rules、annotations和Resources进行单元测试(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5795091.html 使用自定义JUnit Rules.ann ...

随机推荐

  1. vim 的配色方案

    浅色: http://www.vimninjas.com/2012/09/14/10-light-colors/ 深色: http://www.vimninjas.com/2012/08/26/10- ...

  2. python学习之路-11 多线程、多进程、协程

    python内置队列模块 queue queue的四种队列 q = queue.Queue() # 先进先出队列 q = queue.LifoQueue() # 后进先出队列 q = queue.Pr ...

  3. ubuntu下30天自制操作系统还在继续学习中

    操作系统还在学习中,进度不是非常确定,近期学习到了第13天的中部,由于把ucgui移植上去花了一点时间. 同一时候为了方便代码的兴许管理和分享,也为了学习github的代码管理使用思想, 所以建立了一 ...

  4. [Ext JS 4] 实战之Grid, Tree Gird编辑Cell

    前言 本篇这里以稍微复杂一点的Tree Grid 来介绍. 在写编辑grid 之, 先来看一下 grid 的 selType 的配置. 先给一个简单的Tree grid 的例子: Ext.onRead ...

  5. Flexbox属性可视化指南

    Flexbox 布局(国内很多人称为弹性布局)正式的全称为 CSS Flexible Box布局模块,它是CSS3新增的一种布局模式.它可以很方便地用来改善动态或未知大小的元素的对齐,方向和顺序等等. ...

  6. [Python学习笔记][第四章Python字符串]

    2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...

  7. 原来真的不会用指针[*p++]

    Describe: 有2字节字符数据,需要转换成2字节的短整型,字符数据低字节在前. Analyse: 其实就是取一下数据,移位再或一下就好了,大伙都这样想的. Ex1: 假设tmp1就是短整型,p指 ...

  8. struts1:(Struts)ActionForm类及表单数据验证

    在Struts的中央控制器中写了Struts的控制器角色,在这篇介绍下Struts的视图!Struts的视图组件:Struts框架中的视图组件主要包括:JSP页面.ActionForm类.Struts ...

  9. 实现div中图片的滚动

    今日闲来无事自己写了个图片滚动: 源码: <html><head> <meta charset="utf-8"/> <script typ ...

  10. Logging in Java

    Common logging: Log4j1仅仅作为一个实际的日志框架,commons-logging作为门面,统一各种日志框架的混乱格局 基本的commons logging Dependency: ...