Junit4单元测试

caizhu945 贡献于2011-09-04

作者 刘赣平  创建于2009-07-26 06:16:00   修改者chenchong  修改于2009-07-28 02:23:00字数3287

文档摘要:单元测试使用Junit4进行测试,Eclipse内置了Junit4的支持。
关键词:

1. 单元测试规范 单元测试使用Junit4进行测试,Eclipse内置了Junit4的支持。 1) 测试类命名 在项目的service层的实现类都必须编写测试用例 1. 测试用例命名规则为: 类名 + Test。(junit4支持非这样的命名方式,但是为了统一管理,还是采用这样的方式命名) 2. 建立一个和src平行的test包,所有测试用例都放在相应的包内,便于统一管理,合成测试套件。 3. 同一个包的测试用例,合成一个测试套件。 4. 整个工程的测试套件,合成一个统一的测试套件。 2) 测试用例的编写 1. 测试方式都是test开头的方法(testXXXX),JUnit按照在测试用例中的顺序执行。测试方法可以和被测试的方法一一对应,测试方法也可以包含多个被测试的方法。 2. 测试方法中,使用断言(assertXXX和fail,详细资料请查阅JUnit文档)来进行测试结果判断,也可以辅以文字打印说明,如果测试程序抛出异常,则显示为错误,如果断言失败,则显示故障。 3. 测试用例必须覆盖被测试类、方法的所有功能,包括正常情况、异常情况和发生错误的情况都必须覆盖,才能保证测试的完整性。 2. Eclipse中JUnit的用法 这里不详细介绍JUnit的用法,详细的用法自己找文档进行学习。 下面举一个简单的例子说明Eclipse中JUnit的用法: 我们假设我们要写一个整数除法的类,并且给他写测试用例: 1) 建立Math类 /** * @author bulargy.j.bai * @创建时间:Mar 10, 2008 * @描述: */ public class Math { public static int divide(int x,int y) { return x/y; } public static int multiple(int x,int y) { return x*y; } } 2) 建立测试用例 选中需要建立测试用例的包,选择new->other。 这里main方法不需要,我们可以直接用IDE进行测试。 setUp()方法在测试方法前调用,一般用来做测试准备工作。 tearDown()方法在测试方法后调用,一般作测试的清理工作。 setUpBeforeClass()方法在整个类初始化之后调用,一般用来做测试准备工作。 tearDownAfterClass()方法在整个类结束之前调用,一般作测试的清理工作。 constructor()为是否包含构造方法。 选择下一步: 选择需要测试的方法,完成。 系统生成以下代码: /** * @author bulargy.j.bai * @创建时间:Mar 11, 2008 * @描述: */ public class MathTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Test public void testDivide() { fail("Not yet implemented"); } @Test public void testMultiple() { fail("Not yet implemented"); } } 说明: @BeforeClass标签注释的方法用于在整个类测试过程的初始化后调用一次,@AfterClass标签注释的方法则是整个测试类结束之前调用一次。这2个标间的搭配可以避免使用@Before、@After标签组合在每个测试方法前后都调用的弊端,减少系统开销,提高系统测试速度。(不过对环境独立性的测试还是应当使用@Before、@After来完成) @Test标签用来标注待测试的方法,按照类中声明的顺序执行。 我们在testDivide方法加入测试代码,分别测试三种情况: a. 完全正确也没有可能出错的数据,如:9除3 结果必须等于3 b. 可能有问题的边缘数据,如:10除3 结果也必须等于3 c. 错误的数据,如:10除0 必须抛出异常 忽略testMultiple方法 代码如下: @Test(expected=ArithmeticException.class) public void testDivide() { assertEquals(3,Math.divide(9,3)); assertEquals(3,Math.divide(10,3)); Math.divide(10,0); //除数不能为0,会抛出异常 } @Ignore("忽略乘法测试") @Test public void testMultiple() { } 说明: Junit4为测试方法增加了判断异常的方式,避免了以前还要通过try/catch块捕捉异常再抛出的复杂方式,简单的这样声明“@Test(expected=ArithmeticException.class)”Junit4就会检查此方法是否抛出ArithmeticException异常,如果抛出则测试通过,没抛出则测试不通过(@Test标签还有一些其他参数,例如超时测试,但是由于并不能准确反应实际时间,所以应用较少) @Ignore标签会告诉Junit4忽略它所标注的方法,例如数据库不可用时可以用此标注标注一些测试数据库连接的方法来避免测试失败。 3) 运行测试 或者 系统会打开JUnit透视图,如果测试全部通过,则显示如下,颜色条为绿色: 我们将assertEquals(3,Math.divide(9,3));改成assertEquals(2,Math.divide(9,3));则显示如下,颜色条为红色: 可以对错误或者故障的地方进行追踪。 4) 创建测试套件 测试套件可以将多个测试用例合在一起测试,将相关的测试用例合成一个测试套件,在做一个修改后,只需要运行测试套件就可以,不需要运行每一个测试用例。 Junit4没有采用以前的套件测试方法,同样使用annotation的方式来进行。简单在你所要构建测试套件的包里创建一个文件,一般以包名+4Suite 下面我在上面的测试包中复制一下之前的测试类并且一个改名字叫做MathTestAnother,新建一个class类叫做Uitl4Suite,代码如下: package org.bj.util; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; /** * @author bulargy.j.bai * @创建时间:Mar 11, 2008 * @描述: */ @RunWith(Suite.class) @SuiteClasses({MathTest.class, MathTestAnother.class}) public class Util4Suite { } 说明: 通过@RunWith和@SuiteClasses标签来注释一个空的包含无参数构造函数的类来作为套件类,将需要组成套件运行的类加到@SuiteClasses的属性中即可。 运行正确后的结构如图: 可以看到运行套件类的结果是2个测试类都进行了测试。 5) 参数测试 修改 testMultiple //@Ignore("忽略乘法测试") @Test public void testMultiple() { assertEquals(result,Math.multiple(faciend,multiplicator)); } 编写参数方法: @Parameters public static Collection multipleValues() { return Arrays.asList(new Object[][] { {3, 2, 6 }, {4, 3, 12 }, {5, 7, 35 }, {6, 7, 42 }, {11, 7, 77 }, {25, 4, 100 }, {34, 3, 102 }, {21, 5, 105 }, {11, 22, 242 }, {8, 9, 72 }}); } 说明: 需要使用@Parameters标签注解一个静态的返回集合对象的方法 增加成员变量和构造函数: int faciend; int multiplicator; int result; public MathTest(int faciend, int multiplicator, int result) { this.faciend = faciend; this.multiplicator = multiplicator; this.result = result; } 说明: 注意类型要匹配好,不要搞错了 最后在给测试类增加如下注释: @RunWith(Parameterized.class) OK,大功告成。测试看看,结果如下: 成功运行了9次。 Service层测试 本测试属于集成测试,由于现在的DAO都是由逆向工程生成得来,故个人认为没有单独对DAO进行单元测试的必要,可以由对Service层的集成测试来代替对DAO的单元测试。 要使用JUnit来实现Spring以来注入的Service测试时,须将JUnit的jar包至于XFire的jar包之前,否则会报出如下错误: 测试类继承AbstractTransactionalDataSourceSpringContextTests: 实现父类的getConfigLocations来加载sessionfactory 注意配置文件的尾部以“*”结尾,否则会报出找不配置文件的错,如图所示: 在测试方法中使用上下文来直接得到Bean 注:在使用此方法测试时无法使用@Parameters标签及@RunWith标签来实现参数测试。 代码改造:由于如上方式测试无法使用@Parameters标签及@RunWith,原因是此类继承了AbstractTransactionalDataSourceSpringContextTests,故而不支持Junit的标签。所以改造代码如下: 构造工具类来导入Spring: 然后改造测试代码 调用BO的代码改为: 这样就不用继承AbstractTransactionalDataSourceSpringContextTests来实现Spring的注入了。 添加类属性: 增加构造函数: 同时增加@Parameters标签: 最后添加@RunWith标签 这样此测试类就变为一个普通的Junit测试类了。 Action单元测试 由于使用的为struts1.3,struts中使用了需要web容器进行初始化的request与response对象,故引入插件进行单元测试。 首先引入jar包:。  StrutsTestCase支持使用框架来模拟web服务器容器的模拟测试方法,或者在服务器容器(如Tomcat)内使用Cactus框架进行测试的容器内测试方法。一般来说,我更喜欢模拟测试方法,因为这种方法更为轻量级,运行更快,从而可以实现更紧凑的开发周期,这样就不用每次测试都启动WEB容器了。 同样给出Spring的工具类: 构造测试类继承MockStrutsTestCase 重写setUp方法。 注意,此时的setContextDirectory为测试项目的物理路径 setConfigFile设置为stucts-config.xml的位置。 然后完成测试方法: setRequestPathInfo为被测Action的地址 用addRequestParameter方法加入request的参数,注意如果被测目标是继承 DispatchAction的话,请加入method参数。 actionPerform来执行action 然后可以使用assert来进行断言,也可使用StrutsTestCase提供一些方法来进行断言。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档