- 浏览: 58664 次
- 性别:
- 来自: 厦门
文章分类
最新评论
通向架构师的道路(第二十五天)SSH的单元测试与dbunit的整合
一、前言
在二十三天中我们介绍了使用maven来下载工程的依赖库文件,用ant来进行war包的建立。今天我们在这个基础上将使用junit+dbunit来进行带有单元测试报告的框架的架构。
目标:
- 每次打包之前自动进行单元测试并生成单元测试报告
- 生成要布署的打包文件即war包
- 单元测试的代码不能够被打在正式的要布署的war包内,单元测试仅用于unit test用
- 使用模拟数据对dao层进行测试,使得dao方法的测试结果可被预料
二、Junit+Ant生成的单元测试报告
<target name="junitreport"> <junit printsummary="on" haltonfailure="false" failureproperty="tests.failed" showoutput="true"> <classpath> <pathelement path="${dist.dir}/${webAppQAName}/WEB-INF/classes" /> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> <fileset dir="${ext-lib.dir}"> <include name="*.jar" /> </fileset> </classpath> <formatter type="xml" /> <batchtest todir="${report.dir}"> <fileset dir="${dist.dir}/${webAppQAName}/WEB-INF/classes"> <include name="org/sky/ssh/ut/Test*.*" /> </fileset> </batchtest> </junit> <junitreport todir="${report.dir}"> <fileset dir="${report.dir}"> <include name="TEST-*.xml" /> </fileset> <report format="frames" todir="report" /> </junitreport> <fail if="tests.failed"> --------------------------------------------------------- One or more tests failed, check the report for detail... --------------------------------------------------------- </fail> </target>
在一般的产品级开发时或者是带有daily building/nightly building的项目组中我们经常需要检查最新check in的代码是否影响到了原有的工程的编译,因为每天都有程序员往源码服务器里check in代码,而有时我们经常会碰到刚刚被check in的代码在该程序员本地跑的好好的,但是check in源码服务器上后别人从源码服务器“拉”下来的最新代码跑不起来,甚至编译出错,这就是regression bug,因此我们每天的打包要干的事情应该是:
- 程序员check in代码时必须把相关的unit test也check in源码服务器
- 次日的零晨由持续集成构件如:cruisecontrol自动根据设好的schedule把所有的源码服务器的代码进行编译
- 运行单元测试
- 生成报告
- 打包布署到QA服务器上去
三、如何在Spring下书写一个单元测试方法
3.1使用spring的注入特性书写一个单元测试
- 所有的测试类必须以Test开头
- 所有的测试方法名必须为public类型并且以test开头
- 所有的测试类全部放在test/main/java目录下,不可和src/main/java混放
类 org.sky.ssh.ut.BaseSpringContextCommon
package org.sky.ssh.ut; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "/spring/appconfig/applicationContext.xml", "/org/sky/ssh/ut/ds/datasource.xml", "/spring/hibernate/hibernate.xml" }) public class BaseSpringContextCommon { }
org.sky.ssh.ut.ds.datasource.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> <!-- configure data base connection pool by using JNDI --> <!-- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>${jdbc.jndiname}</value> </property> </bean> --> <!-- configure data base connection pool by using C3P0 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}" /> <property name="jdbcUrl" value="${jdbc.databaseURL}" /> <property name="user" value="alpha_test" /> <property name="password" value="password_1" /> <property name="initialPoolSize" value="10" /> <property name="minPoolSize" value="10" /> <property name="maxPoolSize" value="15" /> <property name="acquireIncrement" value="1" /> <property name="maxIdleTime" value="5" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="submit*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="del*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="upd*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> <tx:method name="query*" read-only="true" /> <tx:method name="find*" read-only="true" /> <tx:method name="get*" read-only="true" /> <tx:method name="view*" read-only="true" /> <tx:method name="search*" read-only="true" /> <tx:method name="check*" read-only="true" /> <tx:method name="is*" read-only="true" /> <tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* org.sky.ssh.service.impl.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config> </beans>
<property name="password" value="password_1" />
我们先来书写一个单元测试类吧
org.sky.ssh.ut.TestLoginDAO
package org.sky.ssh.ut; import static org.junit.Assert.assertEquals; import javax.annotation.Resource; import org.junit.Test; import org.sky.ssh.dao.LoginDAO; import org.springframework.test.annotation.Rollback; public class TestLoginDAO extends BaseSpringContextCommon { @Resource private LoginDAO loginDAO; @Test @Rollback(false) public void testLoginDAO() throws Exception { String loginId = "alpha"; String loginPwd = "aaaaaa"; long answer = loginDAO.validLogin(loginId, loginPwd); assertEquals(1, answer); } }
很简单吧,把原来的LongDAO注入进我们的单元测试类中,然后在test方法前加入一个@Test代码该方法为“单元测试”方法即可被junit可识别,然后我们调用一下LoginDAO中的.validLogin方法,测试一下返回值。
运行方法为:
在eclipse打开该类的情况下右键->run as Junit Test
然后选junit4来运行,运行后直接出错抛出:
Class not found org.sky.ssh.ut.TestLoginDAO java.lang.ClassNotFoundException: org.sky.ssh.ut.TestLoginDAO at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:693) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:429) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
这样一个错误,为什么?
其原因在于我们的工程是在eclipse里使用的m2 eclipse这个插件生成的,因此在做单元测试时由于我们的unit test的类是放在test/main/java这个目录下,而这个目录是我们手工建的,因此eclipse不知道这个目录的对应的编译输出的class的目录了.
没关系,按照下面的方法:
右键->选择run as->run configuration,打开如下的设置
选择classpath这个选项栏
- 单击user Entries
- 单击Advanced按钮
- 在弹出框中选择Add Folders
- 点ok按钮
3.2 结合dbunit来做单元测试
我们有了junit为什么还要引入一个dbunit呢?这不是多此一举吗?
试想一下下列场景:
我们开发时连的是开发用的数据库,一张表里有一堆的数据,有些数据不是自己的插的是其它的开发人员插的,那么我想要测试一个dao或者是service方法,获得一个List,然后判断这个List里的值是否为我想要的时候,有可能会碰到下属这样的情况:
运行我的service或者dao方法得到一个list,该list含有6个值,但正好在运行时另一个开发人员因为测试需要往数据库里又插了一些值,导致我的测试方法失败,对不对,这种情况是有可能的。
怎么办呢?比较好的做法是我们需要准备一份自己的业务数据即prepare data,因为是我们自己准备的数据数据,因此它在经过这个方法运行后得到的值,这个得到的值是要经过一系列的业务逻辑的是吧?因此这个得到的值即:expected data是可以被精确预料的。
因此,我们拿着这个expected data与运行了我们的业务方法后得到的结果进行比对,如果比对结果一致,则一定是测试成功,否则失败,对吧?
这就是我们常说的,测试用数据需要是一份干净的数据。
那么为了保持我们的数据干净,我们在测试前清空我们的业务表,插入数据,运行测试地,比对结果,删除数据(也可以不删除,因为每次运行时都会清空相关的业务表),这也就是为什么我们事先要专门搞一个数据库或者是数据库实例,在运行单元测试时我们的数据库连接需要指向到这个单元测试专用的数据库的原因了,见下面的测试流程表:
有了DbUnit,它就可以帮助我们封装:
- 准备测试用数据
- 清空相关业务表
- 插入测试数据
- 比对结果
- 清除先前插入的业务数据
3.3 构建spring+junit+dbunit的框架
org.sky.ssh.ut.util.CleanTableXmlAdapter
package org.sky.ssh.ut.util; import org.dom4j.Element; import org.dom4j.VisitorSupport; import java.util.*; public class CleanTableXmlAdapter extends VisitorSupport { private ArrayList tableList = new ArrayList(); public CleanTableXmlAdapter() { } public void visit(Element node) { try { if ((node.getName().toLowerCase()).equals("table")) { TableBean tBean = new TableBean(); tBean.setTableName(node.getText()); tableList.add(tBean); } } catch (Exception e) { } } public ArrayList getTablesList() { if (tableList == null || tableList.size() < 1) { return null; } else { return tableList; } } }
org.sky.ssh.ut.util.TableBean
package org.sky.ssh.ut.util; import java.io.*; public class TableBean implements Serializable{ private String tableName = ""; public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } }
org.sky.ssh.ut.util.XmlUtil
package org.sky.ssh.ut.util; import java.util.*; import java.io.*; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.VisitorSupport; import org.dom4j.io.SAXReader; import org.springframework.core.io.ClassPathResource; public class XmlUtil { public ArrayList getCleanTables(String xmlFile) { ArrayList tablesList = new ArrayList(); try { SAXReader reader = new SAXReader(); File file = new File(xmlFile); Document doc = reader.read(file); CleanTableXmlAdapter xmlAdapter = new CleanTableXmlAdapter(); doc.accept(xmlAdapter); tablesList = xmlAdapter.getTablesList(); return tablesList; } catch (Exception e) { e.printStackTrace(); return null; } } }
3.4使用框架
test_del_table.xml文件
<?xml version="1.0" encoding="UTF-8"?> <Tables> <table>t_student</table> </Tables>
test_insert_table.xml文件
<?xml version="1.0" encoding="UTF-8"?> <dataset> <t_student student_no="101" student_name="alice"/> <t_student student_no="102" student_name="jil"/> <t_student student_no="103" student_name="leon"/> <t_student student_no="104" student_name="chris"/> <t_student student_no="105" student_name="Ada Wong"/> </dataset>
测试类org.sky.ssh.ut.TestStudentService
package org.sky.ssh.ut; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileInputStream; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.annotation.Resource; import javax.sql.DataSource; import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.DefaultDataSet; import org.dbunit.dataset.DefaultTable; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.ext.mysql.MySqlDataTypeFactory; import org.dbunit.operation.DatabaseOperation; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.sky.ssh.service.StudentService; import org.sky.ssh.ut.util.TableBean; import org.sky.ssh.ut.util.XmlUtil; import org.sky.ssh.vo.StudentVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.test.annotation.Rollback; public class TestStudentService extends BaseSpringContextCommon { private final static String INSERT_TBL = "org/sky/ssh/ut/xmldata/student/test_insert_table.xml"; private final static String DEL_TBL = "org/sky/ssh/ut/xmldata/student/test_del_table.xml"; @Autowired private DataSource dataSource; @Resource private StudentService stdService; @SuppressWarnings("deprecation") @Before public void setUp() throws Exception { IDatabaseConnection connection = null; try { connection = new DatabaseConnection(DataSourceUtils.getConnection(dataSource)); DatabaseConfig config = connection.getConfig(); config.setProperty("http://www.dbunit.org/properties/datatypeFactory", new MySqlDataTypeFactory()); //trunkTables(connection); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL url = classLoader.getResource(INSERT_TBL); if (url == null) { classLoader = ClassLoader.getSystemClassLoader(); url = classLoader.getResource(INSERT_TBL); } IDataSet dateSetInsert = new FlatXmlDataSetBuilder().build(new FileInputStream(url.getFile())); DatabaseOperation.CLEAN_INSERT.execute(connection, dateSetInsert); } catch (Exception e) { e.printStackTrace(); throw e; } finally { if (connection != null) { connection.close(); } } } @After public void tearDown() throws Exception { IDatabaseConnection connection = null; try { connection = new DatabaseConnection(DataSourceUtils.getConnection(dataSource)); DatabaseConfig config = connection.getConfig(); config.setProperty("http://www.dbunit.org/properties/datatypeFactory", new MySqlDataTypeFactory()); //trunkTables(connection); } catch (Exception e) { e.printStackTrace(); throw e; } finally { if (connection != null) { connection.close(); } } } private void trunkTables(IDatabaseConnection connection) throws Exception { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL url = classLoader.getResource(DEL_TBL); if (url == null) { classLoader = ClassLoader.getSystemClassLoader(); url = classLoader.getResource(DEL_TBL); } XmlUtil xmlUtil = new XmlUtil(); List tablesList = xmlUtil.getCleanTables(url.getFile()); Iterator it = tablesList.iterator(); while (it.hasNext()) { TableBean tBean = (TableBean) it.next(); IDataSet dataSetDel = new DefaultDataSet(new DefaultTable(tBean.getTableName())); DatabaseOperation.DELETE_ALL.execute(connection, dataSetDel); } } @Test @Rollback(false) public void testGetAllStudent() throws Exception { List<StudentVO> stdList = new ArrayList<StudentVO>(); stdList = stdService.getAllStudent(); assertEquals(5, stdList.size()); } }
- 该测试方法每次都清空t_student表
- 往t_student表里注入5条数据
- 运行业务方法getAllStudent
- 比较getAllStudent方法返回的list里的size是否为5
- 清空注入的数据(也可不用去清空)
四、将ant与我们的单元测试框架连接起来并生成单元测试报告
build.properties文件
# ant appName=myssh2 webAppName=myssh2 webAppQAName=myssh2-UT local.dir=C:/eclipsespace/${appName} src.dir=${local.dir}/src/main/java test.src.dir=${local.dir}/test/main/java dist.dir=${local.dir}/dist report.dir=${local.dir}/report webroot.dir=${local.dir}/src/main/webapp lib.dir=${local.dir}/lib ext-lib.dir=${local.dir}/ext-lib classes.dir=${webroot.dir}/WEB-INF/classes resources.dir=${local.dir}/src/main/resources
build.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project name="myssh2" default="buildwar" xmlns:artifact="urn:maven-artifact-ant"> <property file="build.properties" /> <property name="classes.dir" value="${dist.dir}/${webAppName}/WEB-INF/classes" /> <path id="maven-ant-tasks.classpath" path="C:/ant/lib/maven-ant-tasks-2.1.3.jar" /> <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" /> <artifact:pom id="maven.project" file="pom.xml" /> <artifact:dependencies filesetId="deps.fileset.compile" useScope="compile"> <!--<pom file="pom.xml"/>--> <pom refid="maven.project" /> </artifact:dependencies> <path id="compile.classpath"> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> </path> <target name="clean" description="Delete old build and dist directories"> <delete dir="${dist.dir}" /> <delete dir="${report.dir}" /> <mkdir dir="${report.dir}" /> <mkdir dir="${dist.dir}" /> <!-- create war structure for production env--> <mkdir dir="${dist.dir}/${webAppName}" /> <mkdir dir="${dist.dir}/${webAppName}/WEB-INF" /> <mkdir dir="${dist.dir}/${webAppName}/WEB-INF/lib" /> <mkdir dir="${dist.dir}/${webAppName}/WEB-INF/classes" /> <mkdir dir="${dist.dir}/${webAppName}/css" /> <mkdir dir="${dist.dir}/${webAppName}/images" /> <mkdir dir="${dist.dir}/${webAppName}/jsp" /> <!-- create war structure for qa env --> <mkdir dir="${dist.dir}/${webAppQAName}" /> <mkdir dir="${dist.dir}/${webAppQAName}/WEB-INF" /> <mkdir dir="${dist.dir}/${webAppQAName}/WEB-INF/lib" /> <mkdir dir="${dist.dir}/${webAppQAName}/WEB-INF/classes" /> <mkdir dir="${dist.dir}/${webAppQAName}/WEB-INF/classes/org/sky/ssh/ut/ds" /> <mkdir dir="${dist.dir}/${webAppQAName}/WEB-INF/classes/org/sky/ssh/ut/xmldata/student" /> <mkdir dir="${dist.dir}/${webAppQAName}/css" /> <mkdir dir="${dist.dir}/${webAppQAName}/images" /> <mkdir dir="${dist.dir}/${webAppQAName}/jsp" /> </target> <target name="download-libs" depends="clean"> <copy todir="${lib.dir}"> <fileset refid="deps.fileset.compile" /> <mapper type="flatten" /> </copy> </target> <target name="compile" description="Compile java sources" depends="download-libs"> <!-- compile main class --> <javac debug="true" destdir="${dist.dir}/${webAppName}/WEB-INF/classes" includeAntRuntime="false" srcdir="${src.dir}"> <classpath refid="compile.classpath" /> </javac> <copy todir="${dist.dir}/${webAppName}/WEB-INF/lib"> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}/WEB-INF/classes"> <fileset dir="${resources.dir}"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}/css"> <fileset dir="${webroot.dir}/css"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}/images"> <fileset dir="${webroot.dir}/images"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}/jsp"> <fileset dir="${webroot.dir}/jsp"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}"> <fileset dir="${webroot.dir}"> <include name="*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppName}/WEB-INF"> <fileset dir="${webroot.dir}/WEB-INF"> <include name="*.*" /> </fileset> </copy> </target> <target name="compileQA" description="Compile java sources" depends="compile"> <!-- compile main class --> <javac debug="true" destdir="${dist.dir}/${webAppQAName}/WEB-INF/classes" includeAntRuntime="false" srcdir="${src.dir}"> <classpath refid="compile.classpath" /> </javac> <javac debug="true" destdir="${dist.dir}/${webAppQAName}/WEB-INF/classes" includeAntRuntime="false" srcdir="${test.src.dir}"> <classpath refid="compile.classpath" /> </javac> <copy todir="${dist.dir}/${webAppQAName}/WEB-INF/lib"> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/WEB-INF/classes"> <fileset dir="${resources.dir}"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/css"> <fileset dir="${webroot.dir}/css"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/images"> <fileset dir="${webroot.dir}/images"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/jsp"> <fileset dir="${webroot.dir}/jsp"> <include name="**/*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}"> <fileset dir="${webroot.dir}"> <include name="*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/WEB-INF"> <fileset dir="${webroot.dir}/WEB-INF"> <include name="*.*" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/WEB-INF/classes/org/sky/ssh/ut/ds"> <fileset dir="${test.src.dir}/org/sky/ssh/ut/ds"> <include name="*.xml" /> </fileset> </copy> <copy todir="${dist.dir}/${webAppQAName}/WEB-INF/classes/org/sky/ssh/ut/xmldata/student"> <fileset dir="${test.src.dir}/org/sky/ssh/ut/xmldata/student"> <include name="*.xml" /> </fileset> </copy> <antcall target="junitreport"> </antcall> </target> <target name="buildwar" depends="compileQA"> <war warfile="${dist.dir}/${webAppName}.war"> <fileset dir="${dist.dir}/${webAppName}" /> </war> </target> <target name="junitreport"> <junit printsummary="on" haltonfailure="false" failureproperty="tests.failed" showoutput="true"> <classpath> <pathelement path="${dist.dir}/${webAppQAName}/WEB-INF/classes" /> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> <fileset dir="${ext-lib.dir}"> <include name="*.jar" /> </fileset> </classpath> <formatter type="xml" /> <batchtest todir="${report.dir}"> <fileset dir="${dist.dir}/${webAppQAName}/WEB-INF/classes"> <include name="org/sky/ssh/ut/Test*.*" /> </fileset> </batchtest> </junit> <junitreport todir="${report.dir}"> <fileset dir="${report.dir}"> <include name="TEST-*.xml" /> </fileset> <report format="frames" todir="report" /> </junitreport> <fail if="tests.failed"> --------------------------------------------------------- One or more tests failed, check the report for detail... --------------------------------------------------------- </fail> </target> </project>
对照着上面的build的流程图,很容易看懂
相关推荐
SSH单元测试与DbUnit整合 在软件开发过程中,单元测试是一个非常重要的步骤,它可以确保代码的正确性和可靠性。今天,我们将讨论如何使用JUnit和DbUnit进行单元测试,并将其与SSH整合。 SSH单元测试 在SSH项目中...
在IT行业中,尤其是在软件开发领域,单元测试是保证代码质量、可维护性和可扩展性的重要...在实际项目中,一个良好的测试策略能够帮助我们更快地发现和修复问题,提高开发效率,这也是通向架构师道路的关键步骤之一。
8. **通向架构师的道路(第二十五天)SSH的单元测试与dbunit的整合.docx** 单元测试是保证代码质量的重要手段,而DbUnit则支持数据库的单元测试。文档可能讲述了如何使用JUnit、Mockito等工具,结合DbUnit进行SSH...
而SSH的单元测试与dbunit的整合,则是保证代码质量与系统稳定性的有效手段。 最后,文章提到了架构与设计文档的写作技巧,以及IBM网格计算和企业批处理任务架构,这些内容提升了架构师的软技能,有助于更好地规划和...
DBUnit 是一个强大的Java库,专门用于数据库的单元测试。它与JUnit和其他测试框架结合使用,可以帮助开发者在数据库层面上确保代码的正确性。DBUnit 提供了一种结构化的方式来导入和导出数据库数据,使得测试环境...
DbUnit则是一个专门用于数据库单元测试的工具,它允许开发者在测试前后对数据库的状态进行操作,如填充测试数据、清理数据等,以保证每次测试都在一致的环境中进行。 首先,了解JUnit4的基础知识至关重要。JUnit4...
unitils整合dbunit利用excel进行单元测试 包含mock以及整合spring进行测试
`dbunit` 是一个与`Junit`配合使用的扩展库,专注于数据库的单元测试。它允许开发者在测试前后填充或清理数据库数据,确保每次测试都在一致的环境中进行。`dbunit` 提供了一种名为“数据集”的概念,数据集是一个XML...
DbUnit 是一个专门为Java开发人员设计的开源工具,主要用于数据库系统的单元测试。它与JUnit紧密集成,使得在执行单元测试时能够对数据库的状态进行精确控制,确保测试的可重复性和可靠性。DbUnit 2.2.3 版本是这个...
本文将深入探讨如何将Spring与DBUnit整合,以实现高效、可靠的数据库集成测试。 首先,理解Spring的核心功能是至关重要的。Spring是一个开源的Java平台,它为构建应用程序提供了全面的支持,包括依赖注入...
DBUnit 是一个强大的开源工具,专门用于数据库的单元测试,它是JUnit框架的一个扩展,使得开发者在进行测试时能够更有效地管理和控制数据库的状态。这个工具的主要目的是确保测试的隔离性和可重复性,使得每次测试都...
DbUnit 是一个开源工具,专为数据库驱动的代码单元测试设计。它允许开发者精确地控制测试环境中的数据库状态,确保测试的独立性和可重复性。在单元测试中,特别是当测试对象涉及到数据库操作,如 DAO(Data Access ...
DBUnit与H2内存数据库结合是进行单元测试的一种高效方法,尤其在开发Java应用程序时,它可以帮助开发者确保数据层的功能正确性。这篇文章将详细介绍如何利用DBUnit和H2内存数据库来构建单元测试环境。 首先,DBUnit...
在Spring框架中,进行Dao层的集成单元测试时,常常会结合Dbunit工具来实现数据库相关的测试。Dbunit是一款强大的Java库,它扩展了JUnit,为数据库提供了结构化数据的导入和导出,使得测试更加方便和可靠。下面将详细...
DbUnit 是一个开源的 Java 库,专门设计用于数据库的单元测试。它扩展了流行的单元测试框架 JUnit,使得在测试代码与数据库交互时能够更好地控制数据库的状态。通过 DbUnit,开发者可以设置和清理测试环境中的数据库...
DbUnit是一款开源的数据库功能测试框架,使用它可以对数据库的基本操作进行白盒单元测试,对输入输出进行校验,从而保证数据的有效性。DbUnit使用XML文件提供测试数据,为测试人员增加了测试难度,降低了单元测试效率。...
DBUnit 是一个 Java 编程语言的开源工具,专门用于数据库的单元测试。它与JUnit 结合使用,提供了一种结构化的方法来设置和验证数据库的状态,确保代码的正确性。在进行数据库驱动的应用程序开发时,DBUnit 可以帮助...
#### 二、数据库单元测试测试流程介绍 **2.1 数据库单元测试的原因** 数据库单元测试对于确保应用程序的正确性和稳定性至关重要。它可以帮助发现早期阶段的问题,减少后期修复的成本,并提高整体代码质量。 **2.2...