JUnit in java 真正的测试用例实战

 单元测试基础

  当今软件测试十分盛行时,本人通过项目实践和个人亲身体会浅谈单元测试,本人一直坚持“用代码说话的原则”,同时也希望个人能给出宝贵意见,共同探讨、共同进步,为中国软件事业有更大的发展共同奋斗!

  最早我们项目组开发的项目时,写代码都是从底层一直写到表现层到jsp,然后开发人员在web层调试页面,近乎98%都会报一大堆exception,然后再在代码中加断点一步一步查到底哪一层代码出现问题……,比较好点做法就是在各个类中加上main方法测试,但总体很不理想,给web层开发人员的调试和质量控制人员带来繁重的工作压力;使用单元测试后,针对每一个方法都做严格的把关,大大减少调试的时间;同时质量控制人员返回过来的bug少了近60%,现在对于开发人员写测试用例非常熟练,并且本人根据实际情况对测试用例做了点小小改动(这部分主要在后面代码中详述),带来很好的效果!

  单元测试到底给实际开发带来什么好处那?

  (1) 首先对于开发人员来说大大减少调试工作的时间,同时也规范了对于代码安全管理(我们知道那些方法是可以调用的);

  (2) 对于整个项目来说,有了完整的测试,保证项目最后交付测试有了可靠依据;

  (3) 对于测试人员大大减少bug的反馈;

  (4) 对于项目经理整个项目达到很好的可控;

  (5) 最主要的完整的单元测试给后期维护人员带来很大的便捷!

  单元测试好处可能还有很多,但本人只能理解和感悟这么多,希望观者补充!

  单元测试配置:

  我将使用eclipse+myEclopse给大家介绍关于JUNIT的环境的简单配置;右键点击项目选择“属性”,在弹出窗口中到环境变量中添加junit.jar包,这样下一步我们就可以进行单元测试了;

  使用eclipse快速开发test Case:

  如下图:右键选择你要测试的类,在新建中点击“JUnit 测试用例”,

  弹出对话框,配置测试名称和根目录,添加注释等,再点击“下一步”到下图:



选择你要测试类中的方法,点击完成!便生成测试类的基本框架,如下代码,我们以对一个DAO类测试为例:


/**//*

* Copyright reserved 2005 by XXXXCo. Ltd.

* Author:Fu wei Date:2006-9-4

*/

import junit.framework.TestCase;

/** *//**

* @author Fu wei

*/

public class OrgTypeDAOTest extends TestCase ...{

/** *//**

* @param arg0

*/

public OrgTypeDAOTest(String arg0) ...{

super(arg0);

}

/**//*

* @see junit.framework.TestCase#setUp()

*/

protected void setUp() throws Exception ...{

super.setUp();

}

/**//*

* @see junit.framework.TestCase#tearDown()

*/

protected void tearDown() throws Exception ...{

super.tearDown();

}

/** *//**

* 主函数

* @param args

*/

public static void main(String[] args)...{

TestRunner.run(OrgTypeDAOTest .class);

}

/** *//**

* {@link OrgTypeDAO#getOrgTypeList()} 的测试方法。

*/

public final void testGetOrgTypeList() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#insertOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的测试方法。

*/

public final void testInsertOrgTypeInfo() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#deleteOrgTypeInfo(java.lang.String)} 的测试方法。

*/

public final void testDeleteOrgTypeInfo() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#updateOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的测试方法。

*/

public final void testUpdateOrgTypeInfo() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#getOrgTypeInfoById(java.lang.String)} 的测试方法。

*/

public final void testGetOrgTypeInfoById() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#isRepeatOrgTypeInfo(java.lang.String)} 的测试方法。

*/

public final void testIsRepeatOrgTypeInfoString() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#isRepeatOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)} 的测试方法。

*/

public final void testIsRepeatOrgTypeInfoOrgTypeVO() ...{

fail("尚未实现"); // TODO

}

/** *//**

* {@link OrgTypeDAO#getFlatOrgIdByName(java.lang.String)} 的测试方法。

*/

public final void testGetFlatOrgIdByName() ...{

fail("尚未实现"); // TODO

}

}

  JUnit单元测试一共要注意一下几点:

  (1)import junit.framework.TestCase 和 junit.textui.TestRunner;

  (2)继承junit.framework.TestCase ;

  (3)自行添加一个main方法 中调用TestRunner.run(测试类名.class);

  (4)有一个调用super(String)的构造函数;

  以上都是JUnit必有的特征,除以上外,我们发现有许多以test开头的方法,而这些方法正是我们要测试的方法,Junti测试其实采用的是断言的方式,只要我们在所有test开头中的方法对数据添加断言方法,同时提供很多断言的方法,

  当我们写完所有方法策略后,JUnit测试如下图:

  在方法页面中点击右键在“调试方式”或“运行方式”中点击“JUnit 测试”,就运行测试类!

  在执行测试类时,执行的大概过程:

  (1)先执行构造方法public OrgTypeDAOTest(String arg0) ;

  (2)再执行初始化数据方法protected void setUp() ;

  (3)再执行以test开头的测试方法;

  (4)最后执行protected void tearDown()方法清理对象;
如果测试失败或者错误,将会显示一个红色的亮条;如果测试通过将显示绿色亮条;如下图

  这样就把一个整个单元测试操作例子演示完成!

  可能对于一个测试类中有多个方法要测试,对于后面看着的确有些困难,因此,我对上测试类进行简单的调整,如下代码:


import junit.framework.TestCase;

import junit.textui.TestRunner;

import com.zhjy.mock.SpringMock;

/** *//**

* 举例测试类

*/

public class OrgTypeDAOTest extends TestCase ...{ //(1)继承TestCase

//private OrgTypeDAO orgTypeDAO;

//private OrgTypeVO orgTypeVO;

//private String id ;

/** *//**

* 构造方法

* @param arg0

*/

public OrgTypeDAOTest(String arg0) ...{

super(arg0);

}

/**//* 初时化方法

* @see junit.framework.TestCase#setUp()

*/

protected void setUp() throws Exception ...{

super.setUp();

//测试初始话数据调用类 orgTypeDAO和 封装数据的对象orgTypeVO

}

/**//* 执行完清理方法

* @see junit.framework.TestCase#tearDown()

*/

protected void tearDown() throws Exception ...{

//清空 对象 ;==null

//orgTypeDAO =null;

//orgTypeVO =null;

super.tearDown();

}

/** *//**

* 主函数

* @param args

*/

public static void main(String[] args)...{

TestRunner.run(OrgTypeDAOTest.class);

}

/** *//**

* 测试方法

* Test method testOrgTypeInfo

*/

public void testOrgTypeInfo() ...{

//添加

String id = insertOrgTypeInfo();

//列表

orgTypeList();

//修改

updateOrgTypeInfo(id);

//查询

selectOrgTypeInfoById(id);

//校验

iExistOrgByOrgTypeId(id);

//测试是否重复数据方法(add)

isRepeatOrgTypeInfo(orgTypeVO.getName(),"");

//获取数据方法(根据名称)

selectOrgTypeIdByName(orgTypeVO.getName());

//删除

deleteOrgTypeInfo(id);

}

/**//*

*添加初始数据

*/

private void setOrgTypeVOAddInfo() ...{

orgTypeVO.setName("add中海测试");

orgTypeVO.setDescription("add中海测试");

orgTypeVO.setStatus("1");

}

/**//*

*添加初始数据

*/

private void setOrgTypeVOUpdateInfo() ...{

//orgTypeVO.setId(id);

orgTypeVO.setName("add中海测试");

orgTypeVO.setDescription("update中海测试");

orgTypeVO.setStatus("1");

}

/**//*

* 新增方法

* Test method for {@link OrgTypeDAO#insertOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public String insertOrgTypeInfo() ...{

setOrgTypeVOAddInfo();

String id = null;

try...{

id = orgTypeDAO.insertOrgTypeInfo(orgTypeVO);

}catch(Exception e)...{

fail("添加通用组织机构失败!");

}

return id;

}

/**//*

* 更新方法

* Test method for {@link com.zhjy.mltx.dao.OrgTypeDAO#updateOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public void updateOrgTypeInfo(String id) ...{

setOrgTypeVOUpdateInfo();

orgTypeVO.setId(id);

try...{

orgTypeDAO.updateOrgTypeInfo(orgTypeVO);

}catch(Exception e)...{

assertTrue("修改通用组织机构失败!", false);

}

//查询

orgTypeVO = orgTypeDAO.selectOrgTypeInfoById(id);

assertEquals("修改通用组织机构失败!", orgTypeVO.getDescription(), "update中海测试");

}

/**//*

* 获取数据方法(主健)

* Test method for {@link OrgTypeDAO#selectOrgTypeInfoById(java.lang.String)}.

*/

public void selectOrgTypeInfoById(String id) ...{

orgTypeVO = orgTypeDAO.selectOrgTypeInfoById(id);

assertTrue("无法查看一条通用机构名称信息!",orgTypeVO != null);

assertEquals("添加通用组织机构失败!", orgTypeVO.getName(), "add中海测试");

assertEquals("修改通用组织机构失败!", orgTypeVO.getDescription(), "update中海测试");

}

/**//*

* 测试此通用组织机构是否被引用

* Test method for {@link OrgTypeDAO#iExistOrgByOrgTypeId(java.lang.String)}.

*/

public void iExistOrgByOrgTypeId(String id) ...{

boolean isfalse;

try ...{

isfalse = this.orgTypeDAO.iExistOrgByOrgTypeId(id);

assertFalse("通用组织机构校验错误!",isfalse);

} catch (DataAccessException e) ...{

assertTrue("通用组织机构数据操作错误!!",false);

} catch (ObjectNotFoundException e) ...{

assertTrue("id is null!!",false);

}

}

/**//*

* 删除

* Test method for {@link OrgTypeDAO#deleteOrgTypeInfo(java.lang.String)}.

*/

public void deleteOrgTypeInfo(String id) ...{

this.orgTypeDAO.deleteOrgTypeInfo(id);

orgTypeVO = this.orgTypeDAO.selectOrgTypeInfoById(id);

assertNull("删除通用组织机构失败!", orgTypeVO);

}

/**//*

* 获取数据方法(根据名称)

* Test method for {@link OrgTypeDAO#selectOrgTypeIdByName(java.lang.String)}.

*/

public void selectOrgTypeIdByName(String name) ...{

String orgtypeid = orgTypeDAO.selectOrgTypeIdByName(name);

//assertEquals(orgtypeid, id);

assertNotNull("未查出来通用组织机构ID!",orgtypeid);

}

/**//*

* 测试是否重复数据方法

* Test method for {@link OrgTypeDAO#isRepeatOrgTypeInfo(com.zhjy.mltx.vo.OrgTypeVO)}.

*/

public void isRepeatOrgTypeInfo(String name,String id) ...{

//setOrgTypeVOUpdateInfo();

OrgTypeVO orgtypetest = new OrgTypeVO();

orgtypetest.setId(id);

orgtypetest.setName(name);

boolean isTrue = orgTypeDAO.isRepeatOrgTypeInfo(orgtypetest);

//assertEquals("通用组织机构错误数据",isTrue, false);

assertTrue("通用组织机构错误数据", isTrue);

}

/**//*

* 列表方法

* Test method for {@link com.zhjy.mltx.dao.OrgTypeDAO#orgTypeList()}.

*/

public void orgTypeList() ...{

List list = orgTypeDAO.orgTypeList();

assertNotNull("无法获取通用机构名称列表list is null!",list);

}

}

  处理过程:

  (1)把所有以test开头的方法中的方法名称前的test去掉(例如把testOrgTypeList()改为orgTypeList()方法);

  (2)同时添加一个以test开头的方法,并调用测试方法;这样做主要是因为执行测试时JUnit(除本身特有的方法出外)只执行以 test为开头的方法;

  (3)同时大家注意到我还把测试初始数据放到两个private方法中private void setOrgTypeVOAddInfo()和private void setOrgTypeVOUpdateInfo()方法中供调用;

  大家可能认为很简单,就是这样简单的改动带来很大的方便,大家是否注意到,我以后运行测试用例时,只关心public void testOrgTypeInfo() 方法就行了,因为只要各个方法的断言策略定制完成,一般就不会再改动,因此,后期的回归测试还是验收测试,缩小了我们对测试的关注点,同时对后面写 test suite构建整体测试带来极大方便性!其中的好处相信只有使用才能体会!

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-11-01 02:06:29

JUnit in java 真正的测试用例实战的相关文章

Java RESTful Web Service实战(第2版)

Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著 图书在版编目(CIP)数据 Java RESTful Web Service实战 / 韩陆著. -2版. -北京:机械工业出版社,2016.7 (Java核心技术系列) ISBN 978-7-111-54213-1 Ⅰ. J-   Ⅱ. 韩-   Ⅲ. JAVA语言-程序设计   Ⅳ. TP312 中国版本图书馆CIP数据核字(2016)第156331号 Java RESTful Web Servi

Java RESTful Web Service实战(第2版) 2.3 传输格式

2.3 传输格式 本节要考虑的就是如何设计表述,即传输过程中数据采用什么样的数据格式.通常,REST接口会以XML和JSON作为主要的传输格式,这两种格式数据的处理是本节的重点.那么Jersey是否还支持其他的数据格式呢?答案是肯定的,让我们逐一掌握各种类型的实现. 2.3.1 基本类型 Java的基本类型又叫原生类型,包括4种整型(byte.short.int.long).2种浮点类型(float.double).Unicode编码的字符(char)和布尔类型(boolean). 阅读指南 本

《Java 7并发编程实战手册》第六章并发集合

由人民邮电出版社出版的<Java 7并发编程实战手册>终于出版了,译者是俞黎敏和申绍勇,该书将于近期上架.之前并发编程网组织翻译过此书,由于邮电出版社在并发网联系他们之前就找到了译者,所以没有采用并发网的译稿,但邮电出版社将于并发网展开合作,发布该书的样章(样章由并发网挑选,你也可以回帖告诉我们你想看哪一章的样章),并组织赠书活动回馈给活跃读者.活动详情请时刻关注并发网的微博和微信(微信号:ifeves),最后祝各位用餐愉快!:) 本章将介绍下列内容: 使用非阻塞式线程安全列表 使用阻塞式线程

《Java和Android开发实战详解》——1.1节编程语言基础知识

1.1编程语言基础知识 Java和Android开发实战详解 "编程语言"(Programming Language)是人类告诉计算机如何工作的一款语言,如同人与人之间沟通使用自然语言,编程语言被设计用于人类与计算机之间进行沟通.从技术角度来说,编程语言就是一款将执行指令传达给计算机的标准通信技术. 1.1.1 程序.软件与应用程序 在说明编程语言之前,我们需要了解什么是程序.软件与应用程序.简单地说来,编程语言提供了语法,可以让我们编写程序代码来建立程序,程序经编译建立成应用程序后,

《Java和Android开发实战详解》——2.4节Eclipse IDE的项目管理与使用

2.4 Eclipse IDE的项目管理与使用 Java和Android开发实战详解 一个Eclipse的工作空间可以同时拥有多个项目,在Eclipse IDE可以切换不同的工作空间,对于已有的Java项目或Java程序文件,我们可以直接导入到目前打开的工作空间或项目. 2.4.1 切换工作空间 step01Eclipse的工作空间中可以新增项目,但不能打开非此工作空间的其他项目,不过,我们可以将当前工作空间切换成其他工作空间.例如,本书每一章的范例都对应有一个工作空间,我们可以在打开第2章工作

《Java和Android开发实战详解》——1.4节搭建Java开发环境

1.4 搭建Java开发环境 Java和Android开发实战详解 在开发Java应用程序前需要搭建Java的开发环境,首先需要安装JDK,然后即可配合编辑工具或集成开发环境来创建Java应用程序.本书主要介绍如何使用Eclipse集成开发环境来创建Java和Android应用程序. 1.4.1 安装与设置JDK 一般来说,有些集成开发环境会一并安装JDK,例如JBuilder,不过,大部分集成开发环境需要用户自行安装JDK.本书使用的JDK版本是JDK 7(Java SE Developmen

jsf-有没有《经典Java EE企业应用实战》的光盘内容?

问题描述 有没有<经典Java EE企业应用实战>的光盘内容? 有没有<经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发> 的光盘内容? 解决方案 http://down.51cto.com/data/1150461 解决方案二: http://vdisk.weibo.com/s/uamgkixENqRy3

《Java和Android开发实战详解》——2.1节如何构建应用程序

2.1 如何构建应用程序 Java和Android开发实战详解 一般来说,我们使用Java程序语言的目的,就是编写程序代码构建应用程序,以期让计算机执行来解决问题. 2.1.1 如何编写程序代码 程序设计(Programming)很困难吗?事实上,如果你可以引导问路人到达目的地.走迷宫或开车到你家,一步一步详细列出活动流程,就表示你一定可以编写程序代码.不过,在列流程时请注意!计算机一点都不聪明,也不会举一反三,所以,我们需要告诉计算机详细的步骤和信息,不能只有模棱两可的内容. 例如,在北京开车

《Java EE核心框架实战》—— 2.5 将SQL语句作为字符串变量传入

2.5 将SQL语句作为字符串变量传入 Java EE核心框架实战 在MyBatis中也支持将SQL语句当成变量传入. 新建名为sqlStringVar的Java项目,映射文件userinfoMapping.xml的内容如下. <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" &