http://sourceforge.net/projects/easymock/ ant结合junit进行软件自动测试

本文主要是介绍http://sourceforge.net/projects/easymock/ ant结合junit进行软件自动测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://sourceforge.net/projects/easymock/

持续集成实践三,灵感来自于Martin Fowler的“持续集成“一文。可以在www.martinfowler.com看到,国内有人翻译成了中文。

本文假设读者具备如下知识:

1、熟练ant进行java工程编译(参考本人“ant编译java工程”一文)

2、junit知识,看看www.junit.org

 

准备:

1、www.junit.org下载junit.jar

2、xml.apache.org下载xalan.jar(ant 的 juntreport需要用到,xalan最好版本大于2.0,不然你还要下载其他的java库)

 

把junit.jar、xalan.jar拷贝到$ANT_HOME/lib/下面,并且最好加到系统CLASSPATH(junit.jar是肯定要的,xalan.jar就不清楚了)。

 

对自己的程序添加junit测试程序,此处请参考www.junit.org的文档,很简单的。

 

然后在build.xml中添加如下指令,很多东西略过,所以强烈要求读者先完成本人“ant编译java工程”一文)

 

<!-- 单元测试,需要完成compile任务 -->

<target name="test" depends="compile">

<junit printsummary="yes">

<!-- 需要的classpath -->

<classpath refid="classpath"/>

<batchtest>

<!-- 单元测试文件为所有src目录下的*Test.java文件 -->

<fileset dir="${srcDir}"><include name="**/*Test.java"/></fileset>

<!-- 生成格式为xml,也可以用plain或者brief -->

<!-- 为什么生成xml,是为了下一步做report用 -->

<formatter type="xml"/>

</batchtest>

</junit>

<!-- 对xml文件生成相应的html文件在reports目录下 -->

<!-- 如果指定于web可访问的目录,就可以使整个项目组看到单元测试情况 -->

<junitreport todir="reports">

<fileset dir=".">

<include name="TEST-*.xml"/>

</fileset>

<!-- 带有框架,可以用noframes选不带框架 -->

<report format="frames" todir="reports/html"/>

</junitreport>

</target>

 

现在运行ant test,看看reports/下面是不是有了生成的单元测试结果的文件了?

如果有问题可以用ant -debug test看看问题出在哪里?

另外更改源程序,让程序通过测试和通不过测试看看生成的结果如何?

 

EasyMock使用简明手册

    在实际编写unit test的过程中,很多情况下我们会需要使用其他的组件(如和数据库相关的测试)。当我们是使用第三方提供的组件时,这并不是太大的问题,因为我们可以假设他们是无错的。但是一旦这些组件是我们自己的组件时,问题就暴露出来了。

“单元测试出错了,但到底是谁的错。我的?他的?”,这种情况显然违反了测试的独立性原则。出现这种情况使得这个测试无法确切的指出是那个单元出现了问题,照成了排错的困难,而且也浪费了时间。同时,过分的将单元的测试代码依赖于其他单元,也照成了其他一些很现实的问题:

-          在所依赖的单元完成之前,无法顺利的编写单元测试。

-          产生环境的依赖性,如运行一个HttpServletRequest处理器的测试代码必须启动一个servlet容器。

所有这些问题,都可以使用Mock Object来解决。使用它的前提是,所依赖单元的接口必须定义清楚。而EasyMock正是为了这一目的而产生的。

使用目的

       通过模拟unit test所需要的组件,已达到隔离各个unit test的目的。目前的版本1.1,它所需要的环境是jdk1.3.1以上和junit3.8.1以上。

可以从http://sourceforge.net/projects/easymock/处下载。

用法

1.       EasyMock采用“记录-----回放”的工作模式,基本使用步骤:

-          创建Mock对象的控制对象Control

-          从控制对象中获取所需要的Mock对象。

-          记录测试方法中所使用到的方法和返回值。

-          设置Control对象到“回放”模式。

-          进行测试。

-          在测试完毕后,确认Mock对象已经执行了刚才定义的所有操作。

2.       使用举例:假设需要测试的对象是RequestUtil,所需要测试的方法为getBoolean。此时我们需要模拟一个HttpServletRequest对象。

public void testGetStringHttpServletRequestString() {

public void testGetBoolean() {

   //创建Mock对象的控制器

   MockControl  control= MockControl.createControl( HttpServletRequest.class);

   //获取Mock对象

   HttpServletRequest  mock= (HttpServletRequest)control.getMock();

   //设置getBoolean中要使用的方法和返回值

control.expectAndReturn( mock.getParameter( "test"), null);

//设置控制器为replay模式

        control.replay();

        //执行测试

        assertNull( RequestUtil.getString( mock, "test"));

        //确认

        control.verify();

    }

}

通过EasyMock,执行这段测试代码完全不需要启动一个servlet容器,在命令行的方式下即可完成,非常的方便。

3.       记录需要使用的Mock的行为。在使用一个Mock对象之前,需要设置我们要用到的方法,以及每个方法的返回值。对于那些没有设置的方法,一旦调用(控制器处于replay模式),EasyMock就会抛出异常。记录一个方法,通常可以分成2:首先,如同使用正常对象调用这个方法;然后,使用控制器的setReturnValue函数设置即可。在1.1中,提供了expectAndReturn函数,使得2步可以合而为一。主要的函数大致如下:

-          expectAndReturn,设置期望调用的函数,以及返回值

-          expectAndThrow,设置期望调用的函数,同时期望该次调用抛出异常

-          setReturnValue,设置上一次调用的返回值(如上次调用时,request.getparameter( “test”),此处设置request.getparameter( “test”)的返回值)

-          setThrowable,设置上次调用抛出的异常

EasyMock中还可以设置调用所执行的次数,具体细节请参见对应的javaDoc

4.       使用举例:

MockControl  control= MockControl.createControl( HttpServletRequest.class);

HttpServletRequest  mock= (HttpServletRequest)control.getMock();

mock.getParameter( "test");

//设置第一次调用request.getParameter的返回值

control.setReturnValue( null, 1);

//设置第二次调用request.getParameter的返回值

control.setReturnValue("this is a test", 1);

control.replay();

assertEquals( RequestUtil.getString( mock, "test", "haha"), "haha");

assertEquals( RequestUtil.getString( mock, "test"), "this is a test");

control.verify();

5.       Mock对象使用结束后,务必调用控制器的verify函数,以确认Mock对象的方法得到了调用。

6.       调用方法的次序,使用Strict。有时,测试代码依赖于被依赖组件的方法的次序。如在测试与数据库相关代码时,测试代码很有可能是这样的次序:先打开数据库链接,执行操作,关闭链接。为了更好的测试这样的代码,可以使用MockControl.createStrictControl()来创建一个严格的Mock对象控制器,在其中,他会规定Mock出来的对象的调用次序。

以上是EasyMock的主要使用,至于其他的用法,请参见具体的文档。

检查表

       在此列出使用Mock对象来进行unit test需要注意的问题:

    - 当自己动手实现Mock对象时,不要在Mock对象中实现业务逻辑。


作者Blog: http://blog.csdn.net/foxgemm/
在java开发中,ant为我们提供了一个非常强大的项目构建功能。日常开发中,最常用的功能是:编译、打包、运行junit testcase、检查编码规范。在此给出这些最常用功能的一个ant模板文件,与各位共享。
<?xml version="1.0" encoding="gb2312"?>
<project name="Test Project" default="all" basedir=".">

    <property name="src.code" value="src"/>
    <property name="src.junit" value="junit"/>
    <property name="lib.dir" value="lib"/>
    <property name="lib.jar" value="TestClass.jar"/>
   
    <!-- checkstyle configuration -->
    <property name="checkstyle.config" value="checkstyle.xml"/>
    <taskdef resource="checkstyletask.properties"
             classpath="${lib.dir}/checkstyle-all-3.1.jar"/>
   
   
    <!-- 输出文档 -->
    <property name="doc.dir" value="doc"/>
    <property name="doc.api" value="${doc.dir}/api"/>
    <property name="javadoc.package" value="com.*"/>
   
    <!-- 输出二进制文件 -->
    <property name="dist.root" value="dist"/>
    <property name="dist.proj" value="${dist.root}/proj"/>
    <property name="dist.classes" value="${dist.proj}/classes"/>
    <property name="dist.lib" value="${dist.proj}/lib"/>
    <property name="dist.junit" value="${dist.root}/junit"/>
   
    <!-- classpath -->
    <path id="classpath">
        <fileset dir="${lib.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </path>
   
    <path id="proj.libs">
        <fileset dir="${dist.lib}">
            <include name="**/*.jar"/>
        </fileset>      
    </path>
   
    <target name="init">
        <mkdir dir="${doc.dir}"/>
        <mkdir dir="${dist.root}"/>
        <mkdir dir="${dist.proj}"/>
        <mkdir dir="${dist.lib}"/>
        <tstamp/>
        <echo message="${TSTAMP}"></echo>
    </target>
   
    <target name="all" depends="compilesrc, javadoc, checkstyle"/>
   
    <!-- 编译源文件 -->
    <target name="compilesrc" depends="init">
        <mkdir dir="${dist.classes}"/>
        
        <javac destdir="${dist.classes}" deprecation="on">
            <src path="${src.code}"/>
            <classpath refid="classpath"/>
        </javac>

        <jar jarfile="${dist.lib}/${lib.jar}" basedir="${dist.classes}">
            <include name="**/*.class"/>
        </jar>      
    </target>
   
    <!--  产生javadoc -->
    <target name="javadoc" depends="init">
        <mkdir dir="${doc.api}"/>
        
        <javadoc packagenames="${javadoc.package}" sourcepath="${src.code}"
             private="yes" defaultexcludes="yes" destdir="${doc.dir}/api">
            <classpath refid="classpath"/>
        </javadoc>
    </target>
   
    <!--  编译Junit文件 -->
    <target name="compilejunit" depends="compilesrc">
        <mkdir dir="${dist.junit}"/>
        
        <javac destdir="${dist.junit}" deprecation="on">
            <src path="${src.junit}"/>
            <classpath refid="classpath"/>
            <classpath refid="proj.libs"/>
        </javac>        
    </target>
   
    <!-- 运行checkstyle检查代码规范 -->
    <target name="checkstyle" depends="init">
        <checkstyle config="${checkstyle.config}">
            <fileset dir="${src.code}" includes="**/*.java"/>
            <formatter type="plain"/>
            <formatter type="xml" toFile="${dist.root}/checkstyle_errors.xml"/>
        </checkstyle>
    </target>
   
    <!--  运行junit  -->
    <target name="junit" depends="compilejunit">
        <junit printsummary="yes" haltonfailure="yes">
            <classpath>
                <path refid="classpath"/>
                <pathelement location="${dist.junit}"/>
            </classpath>
            
            <formatter type="plain"/>
        
            <!-- test name="com.TestClassTest" haltonfailure="no" outfile="result"/ -->
        
            <batchtest todir="${dist.junit}">
                <fileset dir="${dist.junit}" includes="**/Test*.class" />
            </batchtest>
        </junit>
    </target>
   
    <!-- 清除产生的类、junit相关类、文档 -->
    <target name="clean">
        <delete dir="${dist.classes}"/>
        <delete dir="${dist.junit}"/>
        <delete dir="${doc.api}"/>
    </target>
   
    <!-- 清除所有输出结果 -->
    <target name="cleanall" depends="clean">
        <delete dir="${doc.dir}"/>
        <delete dir="${dist.root}"/>
    </target>
</project>

这篇关于http://sourceforge.net/projects/easymock/ ant结合junit进行软件自动测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/459053

相关文章

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

使用Python进行文件读写操作的基本方法

《使用Python进行文件读写操作的基本方法》今天的内容来介绍Python中进行文件读写操作的方法,这在学习Python时是必不可少的技术点,希望可以帮助到正在学习python的小伙伴,以下是Pyth... 目录一、文件读取:二、文件写入:三、文件追加:四、文件读写的二进制模式:五、使用 json 模块读写

使用zabbix进行监控网络设备流量

《使用zabbix进行监控网络设备流量》这篇文章主要为大家详细介绍了如何使用zabbix进行监控网络设备流量,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装zabbix配置ENSP环境配置zabbix实行监控交换机测试一台liunx服务器,这里使用的为Ubuntu22.04(

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

在Pandas中进行数据重命名的方法示例

《在Pandas中进行数据重命名的方法示例》Pandas作为Python中最流行的数据处理库,提供了强大的数据操作功能,其中数据重命名是常见且基础的操作之一,本文将通过简洁明了的讲解和丰富的代码示例,... 目录一、引言二、Pandas rename方法简介三、列名重命名3.1 使用字典进行列名重命名3.编

python安装完成后可以进行的后续步骤和注意事项小结

《python安装完成后可以进行的后续步骤和注意事项小结》本文详细介绍了安装Python3后的后续步骤,包括验证安装、配置环境、安装包、创建和运行脚本,以及使用虚拟环境,还强调了注意事项,如系统更新、... 目录验证安装配置环境(可选)安装python包创建和运行Python脚本虚拟环境(可选)注意事项安装