- 浏览: 83867 次
- 性别:
- 来自: 北京
JUnit测试骨架
使用JUnit时,主要都是通过继承TestCase类别来撰写测试用例,使用testXXX()名称来撰写单元测试。
用JUnit写测试真正所需要的就三件事:
1. 一个import语句引入所有junit.framework.*下的类。
2. 一个extends语句让你的类从TestCase继承。
3. 一个调用super(string)的构造函数。
功能类MathTool
package com.zj.c01;
public class MathTool {
public static int gcd(int num1, int num2) {
int r = 0;
while (num2 != 0) {
r = num1 % num2;
num1 = num2;
num2 = r;
}
return num1;
}
}
测试类MathToolTest
package com.zj.c01;
import junit.framework.TestCase;
public class MathToolTest extends TestCase {
public MathToolTest(String name) {
super(name);
}
public void testGcd() {
assertEquals(5, MathTool.gcd(10, 5));
}
}
使用Eclipse-Run As JUnit Test
在运行TestRunner执行测试时,你会发现到有Failure与Error两种测试尚未通过的信息。
Failure指的是预期的结果与实际运行单元的结果不同所导致,例如当使用assertEquals()或其它assertXXX()方法断言失败时,就会回报Failure,这时候要检查你的单元方法中的逻辑设计是否有误。
Error指的是你的程序没有考虑到的情况,在断言之前程序就因为某种错误引发例外而终止,例如在单元中存取某个数组,因为存取超出索引而引发 ArrayIndexOutOfBoundsException,这会使得单元方法无法正确完成,在测试运行到asertXXXX()前就提前结束,这时候要检查你的单元方法中是否有未考虑到的情况而引发流程突然中断。
JUnit的各种断言
JUnit提供了一些辅助函数,用于帮助你确定某个被测试函数是否工作正常。通常而言,我们把所有这些函数统称为断言。断言是单元测试最基本的组成部分。
1. assertEquals([String message], expected,actual)
比较两个基本类型或对象是否相等(expected和actual是原始类型数值(primitive value)或者必须为实现比较而具有equal方法);
2.assertFalse([String message],boolean condition)
对布尔值求值,看它是否为“真“;
3.assertTrue([String message],boolean condition)
对布尔值求值,看它是否为“假“;
4.assertNull([String message],java.lang.Object object)
检查对象是否为“空“;
5.assertNotNull([String message],java.lang.Object object)
检查对象是否不为“空”;
6.assertSame([String message],expected,actual)
检查两个对象是否为同一实例;
7.assertNotSame([String message],expected,actual)
检查两个对象是否不为同一实例;
8. fail( String message )
使测试立即失败,其中 message 参数使可选的。这种断言通常被用于标记某个不应该到达的分支(例如,在一个预期发生的异常之后)
一个TestCase测试实例
下面是一个数字功能类,它提供了求最大值函数和求最小值函数:
package com.zj.c01;
public class NumberTool {
public static int getMax(int[] arr) {
int max = Integer.MIN_VALUE;
if (arr.length == 0)
throw new RuntimeException("Empty list");
for (int index = 0; index < arr.length; index++) {
if (arr[index] > max)
max = arr[index];
}
return max;
}
public static int getMin(int[] arr) {
int min = Integer.MAX_VALUE;
if (arr.length == 0)
throw new RuntimeException("Empty list");
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min)
min = arr[i];
}
return min;
}
}
下面针对求最大值函数编写测试用例:
1.简单测试:[7,8,9]->9;
2.位序测试:[9,8,7] ->9;[7,9,8] ->9;[8,7,9] ->9;
3.重复值测试:[9,7,9,8] ->9;
4.单值测试:[1]->1;
5.负值测试:[-7,-8,-9]->-7;
6.空值测试:[]->抛出异常;
测试类NumberToolTest:
package com.zj.c01;
import junit.framework.TestCase;
public class NumberToolTest extends TestCase {
public NumberToolTest(String name) {
super(name);
}
public void testSimple() {
assertEquals(9, NumberTool.getMax(new int[] { 7, 8, 9 }));
}
public void testOrder() {
assertEquals(9, NumberTool.getMax(new int[] { 9, 8, 7 }));
assertEquals(9, NumberTool.getMax(new int[] { 7, 9, 8 }));
assertEquals(9, NumberTool.getMax(new int[] { 8, 7, 9 }));
}
public void testDups() {
assertEquals(9, NumberTool.getMax(new int[] { 9, 7, 9, 8 }));
}
public void testOne() {
assertEquals(1, NumberTool.getMax(new int[] { 1 }));
}
public void testNegitave() {
assertEquals(-7, NumberTool.getMax(new int[] { -7, -8, -9 }));
}
public void testEmpty() {
try {
NumberTool.getMax(new int[] {});
fail("Should have thrown an exception");
} catch (RuntimeException e) {
assertTrue(true);
}
}
}
使用Eclipse-Run As JUnit Test
JUnit和异常
对于测试而言,下面两种异常是我们可能会感兴趣的:
1. 从测试代码抛出的可预测异常。
2. 由于某个模块(或代码)发生严重错误,而抛出的不可预测异常。
任何对assertTrue(true)的使用都应该被翻译为“我预期控制流程会达到这个地方”。通常而言,对于方法中每个被期望的异常,你都应该写一个专门的测试来确认该方法在应该抛出异常的时候确实会抛出异常。如上例中testEmpty()测试方法的设计。
对于处于出乎意料的异常,你最好简单的改变你的测试方法的声明让它能抛出可能的异常。JUnit框架可以捕获任何异常,并且把它报告为一个错误,这些都不需要你的参与。
Per-method的Setup和Tear-down
对于重复出现在各个单元测试中的运行环境,可以集中加以管理,可以在继承TestCase之后,重新定义setUp()与tearDown()方法,将数个单元测试所需要的运行环境在setUp()中创建,并在tearDown()中销毁。
JUnit的TestCase基类提供两个方法供你改写,分别用于环境的建立和清理:
protected void setup();
protected void teardown();
测试类MathToolTest2:
package com.zj.c01;
import junit.framework.TestCase;
public class NumberToolTest2 extends TestCase {
private int[] arr;
public NumberToolTest2(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
arr = new int[] { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
}
protected void tearDown() throws Exception {
super.tearDown();
arr = null;
}
public void testMax() {
assertEquals(5, NumberTool.getMax(arr));
}
public void testMin() {
assertEquals(-5, NumberTool.getMin(arr));
}
}
TestSuite
每一个定义好的TestCase,都使用TestRunner来运行测试,事实上TestRunner并不直接运行TestCase上的单元方法,而是通过TestSuite ,TestSuite可以将数个TestCase组合在一起。
在上面的例子中,并没有看到任何的TestSuite,这是因为TestRunner的run()方法中会建立TestSuite:
static public void run(Class testClass) {
run(new TestSuite(testClass));
}
在这个TestSuite的建构式中,会使用反射自动找出testXXX()方法,并加入待执行的测试方法, TestRunner的run()方法中会去执行TestSuite上的run()方法,然后TestSuite会将之委托给TestCase上的 run()方法,而该run()方法中执行每一个testXXX()方法。
如果你只想执行某TestCase中的部分测试函数,则可自己构建TestSuite,下面的代码针对NumberToolTest中的两个测试函数testSimple()和testNegitave()进行测试。
package com.zj.c02;
import com.zj.c01.NumberToolTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PartTest {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new NumberToolTest("testSimple"));
suite.addTest(new NumberToolTest("testNegitave"));
return suite;
}
}
使用Eclipse-Run As JUnit Test
你也可以组合多个testCase,下面的代码将MathToolTest和NumberToolTest集中到一个TestSuite中:
package com.zj.c02;
import com.zj.c01.MathToolTest;
import com.zj.c01.NumberToolTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class CompositeTest {
public static Test suite() {
TestSuite suite = new TestSuite("Running all tests.");
suite.addTestSuite(MathToolTest.class);
suite.addTestSuite(NumberToolTest.class);
return suite;
}
}
使用Eclipse-Run As JUnit Test
Per-suite Setup和Tear-down
一般而言,你只须针对每个方法设置运行环境;但是在某些情况下,你须为整个test suite设置一些环境,以及在test suite中的所有方法都执行完成后做一些清理工作。要达到这种效果,你需要per-suite setup和per-suite teardown。
Per-suite的setup要复杂一些。你需要提供所需测试的一个suite(无论通过什么样的方式)并且把它包装进一个TestSetup对象。注意你可以在同一个类中同时使用per-sutie和per-test的setup()和teardown。
package com.zj.c02;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestSuite;
import com.zj.c01.MathToolTest;
import com.zj.c01.NumberToolTest;
public class WrapperCompositeTest {
public static Test suite() {
TestSuite suite = new TestSuite("Running all tests with env.");
suite.addTestSuite(MathToolTest.class);
suite.addTestSuite(NumberToolTest.class);
TestSetup wrapper = new TestSetup(suite) {
protected void setUp() {
doSetUp();
}
protected void tearDown() {
doTearDown();
}
};
return wrapper;
}
public static void doSetUp() {
// initialization codes
}
public static void doTearDown() {
// release codes
}
}
使用JUnit时,主要都是通过继承TestCase类别来撰写测试用例,使用testXXX()名称来撰写单元测试。
用JUnit写测试真正所需要的就三件事:
1. 一个import语句引入所有junit.framework.*下的类。
2. 一个extends语句让你的类从TestCase继承。
3. 一个调用super(string)的构造函数。
功能类MathTool
package com.zj.c01;
public class MathTool {
public static int gcd(int num1, int num2) {
int r = 0;
while (num2 != 0) {
r = num1 % num2;
num1 = num2;
num2 = r;
}
return num1;
}
}
测试类MathToolTest
package com.zj.c01;
import junit.framework.TestCase;
public class MathToolTest extends TestCase {
public MathToolTest(String name) {
super(name);
}
public void testGcd() {
assertEquals(5, MathTool.gcd(10, 5));
}
}
使用Eclipse-Run As JUnit Test
在运行TestRunner执行测试时,你会发现到有Failure与Error两种测试尚未通过的信息。
Failure指的是预期的结果与实际运行单元的结果不同所导致,例如当使用assertEquals()或其它assertXXX()方法断言失败时,就会回报Failure,这时候要检查你的单元方法中的逻辑设计是否有误。
Error指的是你的程序没有考虑到的情况,在断言之前程序就因为某种错误引发例外而终止,例如在单元中存取某个数组,因为存取超出索引而引发 ArrayIndexOutOfBoundsException,这会使得单元方法无法正确完成,在测试运行到asertXXXX()前就提前结束,这时候要检查你的单元方法中是否有未考虑到的情况而引发流程突然中断。
JUnit的各种断言
JUnit提供了一些辅助函数,用于帮助你确定某个被测试函数是否工作正常。通常而言,我们把所有这些函数统称为断言。断言是单元测试最基本的组成部分。
1. assertEquals([String message], expected,actual)
比较两个基本类型或对象是否相等(expected和actual是原始类型数值(primitive value)或者必须为实现比较而具有equal方法);
2.assertFalse([String message],boolean condition)
对布尔值求值,看它是否为“真“;
3.assertTrue([String message],boolean condition)
对布尔值求值,看它是否为“假“;
4.assertNull([String message],java.lang.Object object)
检查对象是否为“空“;
5.assertNotNull([String message],java.lang.Object object)
检查对象是否不为“空”;
6.assertSame([String message],expected,actual)
检查两个对象是否为同一实例;
7.assertNotSame([String message],expected,actual)
检查两个对象是否不为同一实例;
8. fail( String message )
使测试立即失败,其中 message 参数使可选的。这种断言通常被用于标记某个不应该到达的分支(例如,在一个预期发生的异常之后)
一个TestCase测试实例
下面是一个数字功能类,它提供了求最大值函数和求最小值函数:
package com.zj.c01;
public class NumberTool {
public static int getMax(int[] arr) {
int max = Integer.MIN_VALUE;
if (arr.length == 0)
throw new RuntimeException("Empty list");
for (int index = 0; index < arr.length; index++) {
if (arr[index] > max)
max = arr[index];
}
return max;
}
public static int getMin(int[] arr) {
int min = Integer.MAX_VALUE;
if (arr.length == 0)
throw new RuntimeException("Empty list");
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min)
min = arr[i];
}
return min;
}
}
下面针对求最大值函数编写测试用例:
1.简单测试:[7,8,9]->9;
2.位序测试:[9,8,7] ->9;[7,9,8] ->9;[8,7,9] ->9;
3.重复值测试:[9,7,9,8] ->9;
4.单值测试:[1]->1;
5.负值测试:[-7,-8,-9]->-7;
6.空值测试:[]->抛出异常;
测试类NumberToolTest:
package com.zj.c01;
import junit.framework.TestCase;
public class NumberToolTest extends TestCase {
public NumberToolTest(String name) {
super(name);
}
public void testSimple() {
assertEquals(9, NumberTool.getMax(new int[] { 7, 8, 9 }));
}
public void testOrder() {
assertEquals(9, NumberTool.getMax(new int[] { 9, 8, 7 }));
assertEquals(9, NumberTool.getMax(new int[] { 7, 9, 8 }));
assertEquals(9, NumberTool.getMax(new int[] { 8, 7, 9 }));
}
public void testDups() {
assertEquals(9, NumberTool.getMax(new int[] { 9, 7, 9, 8 }));
}
public void testOne() {
assertEquals(1, NumberTool.getMax(new int[] { 1 }));
}
public void testNegitave() {
assertEquals(-7, NumberTool.getMax(new int[] { -7, -8, -9 }));
}
public void testEmpty() {
try {
NumberTool.getMax(new int[] {});
fail("Should have thrown an exception");
} catch (RuntimeException e) {
assertTrue(true);
}
}
}
使用Eclipse-Run As JUnit Test
JUnit和异常
对于测试而言,下面两种异常是我们可能会感兴趣的:
1. 从测试代码抛出的可预测异常。
2. 由于某个模块(或代码)发生严重错误,而抛出的不可预测异常。
任何对assertTrue(true)的使用都应该被翻译为“我预期控制流程会达到这个地方”。通常而言,对于方法中每个被期望的异常,你都应该写一个专门的测试来确认该方法在应该抛出异常的时候确实会抛出异常。如上例中testEmpty()测试方法的设计。
对于处于出乎意料的异常,你最好简单的改变你的测试方法的声明让它能抛出可能的异常。JUnit框架可以捕获任何异常,并且把它报告为一个错误,这些都不需要你的参与。
Per-method的Setup和Tear-down
对于重复出现在各个单元测试中的运行环境,可以集中加以管理,可以在继承TestCase之后,重新定义setUp()与tearDown()方法,将数个单元测试所需要的运行环境在setUp()中创建,并在tearDown()中销毁。
JUnit的TestCase基类提供两个方法供你改写,分别用于环境的建立和清理:
protected void setup();
protected void teardown();
测试类MathToolTest2:
package com.zj.c01;
import junit.framework.TestCase;
public class NumberToolTest2 extends TestCase {
private int[] arr;
public NumberToolTest2(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
arr = new int[] { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
}
protected void tearDown() throws Exception {
super.tearDown();
arr = null;
}
public void testMax() {
assertEquals(5, NumberTool.getMax(arr));
}
public void testMin() {
assertEquals(-5, NumberTool.getMin(arr));
}
}
TestSuite
每一个定义好的TestCase,都使用TestRunner来运行测试,事实上TestRunner并不直接运行TestCase上的单元方法,而是通过TestSuite ,TestSuite可以将数个TestCase组合在一起。
在上面的例子中,并没有看到任何的TestSuite,这是因为TestRunner的run()方法中会建立TestSuite:
static public void run(Class testClass) {
run(new TestSuite(testClass));
}
在这个TestSuite的建构式中,会使用反射自动找出testXXX()方法,并加入待执行的测试方法, TestRunner的run()方法中会去执行TestSuite上的run()方法,然后TestSuite会将之委托给TestCase上的 run()方法,而该run()方法中执行每一个testXXX()方法。
如果你只想执行某TestCase中的部分测试函数,则可自己构建TestSuite,下面的代码针对NumberToolTest中的两个测试函数testSimple()和testNegitave()进行测试。
package com.zj.c02;
import com.zj.c01.NumberToolTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PartTest {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new NumberToolTest("testSimple"));
suite.addTest(new NumberToolTest("testNegitave"));
return suite;
}
}
使用Eclipse-Run As JUnit Test
你也可以组合多个testCase,下面的代码将MathToolTest和NumberToolTest集中到一个TestSuite中:
package com.zj.c02;
import com.zj.c01.MathToolTest;
import com.zj.c01.NumberToolTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class CompositeTest {
public static Test suite() {
TestSuite suite = new TestSuite("Running all tests.");
suite.addTestSuite(MathToolTest.class);
suite.addTestSuite(NumberToolTest.class);
return suite;
}
}
使用Eclipse-Run As JUnit Test
Per-suite Setup和Tear-down
一般而言,你只须针对每个方法设置运行环境;但是在某些情况下,你须为整个test suite设置一些环境,以及在test suite中的所有方法都执行完成后做一些清理工作。要达到这种效果,你需要per-suite setup和per-suite teardown。
Per-suite的setup要复杂一些。你需要提供所需测试的一个suite(无论通过什么样的方式)并且把它包装进一个TestSetup对象。注意你可以在同一个类中同时使用per-sutie和per-test的setup()和teardown。
package com.zj.c02;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestSuite;
import com.zj.c01.MathToolTest;
import com.zj.c01.NumberToolTest;
public class WrapperCompositeTest {
public static Test suite() {
TestSuite suite = new TestSuite("Running all tests with env.");
suite.addTestSuite(MathToolTest.class);
suite.addTestSuite(NumberToolTest.class);
TestSetup wrapper = new TestSetup(suite) {
protected void setUp() {
doSetUp();
}
protected void tearDown() {
doTearDown();
}
};
return wrapper;
}
public static void doSetUp() {
// initialization codes
}
public static void doTearDown() {
// release codes
}
}
发表评论
-
敏捷软件开发
2016-08-19 16:32 334敏捷软件开发 敏捷软件开发是一种面临迅速变化的需求快速开 ... -
XML 系列教程
2012-05-06 12:50 612http://www.w3school.com.cn/x.as ... -
MANIFEST.MF是个啥?请给俺个详细解答
2012-02-06 17:48 1051看完下面的帖子你就明 ... -
如何从IT民工跃身成精英
2011-12-19 15:11 803“IT”这个英文缩写 ... -
java_ant详解(转载)
2011-12-17 14:40 12551,什么是ant ant是构建工具 2,什么是构建 概念到处可 ... -
Log4j使用总结
2011-12-14 16:10 1一、介绍 Log4j是Apache的一个开放源代码项目,通过 ... -
Log4j使用总结(转)
2011-12-14 16:08 698一、介绍 Log4j是Apache的一个开放源代码项目,通过 ... -
关于正则表达式的贪婪与非贪婪模式
2011-11-20 15:42 1146以前看正则表达式,但没有注意到正则表达式的贪婪与非贪婪模式,今 ... -
MyEclipse内存不足以及参数配置“ -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M ”
2011-11-19 20:20 2534“MyEclipse has detected that ... -
eclipse中的.project 和 .classpath文件的具体作用 (转)
2011-03-10 15:27 1244.project是项目文件,项目的结构都在其中定义,比如lib ... -
Xpath使用(转载)
2010-08-17 18:38 1085XPath 表达式比繁琐的文档对象模型(DOM)导航代码要容易 ... -
XPath简介(转载)
2010-08-17 18:30 893XPath 简介Previous Page Next Page ... -
根据XML内容设置XSL样式表(转载)
2010-08-17 17:36 1087使用可扩展样式表语言转换(Extensible Stylesh ... -
XSL简介(转载)
2010-08-17 17:35 962XSL 语言 Previous Page Next Page ... -
EasyMock使用手记
2010-08-12 11:45 908Mock 对象能够模拟领域 ... -
EasyMock 使用方法与原理剖析
2010-08-11 18:23 820Mock 方法是单元测试中 ... -
JUNIT入门
2010-08-11 15:32 1082关键字: junit test 1、将junit的jar包放 ...
相关推荐
JUnit 是一个流行的单元测试框架,广泛应用于 Java 项目中,本文将详细介绍 JUnit 测试框架的使用,并提供了两个示例来帮助读者更好地理解和掌握 JUnit 的使用。 一、JUnit 测试框架的使用 为了使用 JUnit 测试...
JUnit测试框架是Java开发者进行单元测试的首选工具,它的出现极大地简化了软件测试的过程,确保代码的质量和稳定性。本文将详细介绍JUnit的使用方法、核心概念以及它在软件开发中的重要性。 首先,JUnit是一个开源...
2. Junit 的本质:Junit 本质上是一套框架,即开发者制定了一套条条框框,遵循这此条条框框要求编写测试代码,如继承某个类,实现某个接口,就可以用 Junit 进行自动测试了。 3. Junit 的优点:由于 Junit 相对独立...
JUnit,作为Java编程语言的事实上的标准测试框架,其在软件开发中的重要性不容忽视。由著名程序员Kent Beck和Erich Gamma发起,JUnit以其简洁而强大的功能,极大地推动了Java开发中的自动化测试实践。Martin Fowler...
jUnit 是一个开源的 Java 语言的单元测试框架,其专门针对 Java 语言设计,使用十分广泛。jUnit 已成事实上的标准单元测试框架(行业标准)。 jUnit 的优点包括:可以使用断言(Assertion)测试期望结果;可以...
本压缩包文件"javaweb中.java文件测试需要的框架(junit测试).rar"显然是为了帮助开发者理解如何在Java Web项目中使用JUnit进行测试。 **JUnit框架详解** JUnit是一个基于注解的测试框架,它的核心功能包括: 1....
要生成 JUnit 测试框架,需要将 JUnit4 单元测试包引入项目中,然后在 Eclipse 的 Package Explorer 中右键点击 Calculator 类,选择“New à JUnit Test Case”,系统将自动生成一个新类 CalculatorTest,里面包含...
JUnit 已经 13 岁了,是一个简单但有效的单元测试框架,世界上无数软件项目使用它。 JUnit 框架的主要组成部分包括测试类、测试运行器和断言。测试类继承 TestCase 类,开发自己的测试驱动程序。测试运行器(Test...
在“22_android下junit测试框架配置.avi”这个视频文件中,很可能是详细讲解了如何在Android项目中配置和使用JUnit进行单元测试,包括添加依赖、创建测试类、编写测试方法,以及如何运行和查看测试结果。观看这个...
Junit作为Java领域最常用的单元测试框架,为开发者提供了简单易用的API来进行测试。本案例涵盖了Spring和Struts两大框架的单元测试,旨在帮助开发者掌握如何对这两个流行的Java Web框架进行有效的测试。 一、Junit...
JUnit是Java编程语言中最常用的单元测试框架之一,它允许开发者编写可重复运行的测试用例,以确保代码的正确性和稳定性。JUnit3.8.1是该框架的一个较早版本,尽管现在已经有更新的版本(如JUnit5),但了解其基本...
Junit是一个用于Java编程语言的单元测试框架,由Kent Beck和Erich Gamma共同开发。它遵循了xUnit架构的基本原则,并且是该领域中最著名的框架之一。Junit提供了简单的断言、测试套件、测试运行器等功能,使得开发者...
**Junit测试框架** Junit是开源项目,由Eclipse基金会维护,广泛应用于Java开发环境。它为每个测试用例提供了独立的运行环境,确保测试的隔离性。Junit提供断言机制,用于验证预期结果是否与实际结果相符,以及注解...
三、Junit测试框架特性 1. 控制测试执行:@Before和@After注解分别用于在每个测试方法之前和之后执行初始化和清理工作。 2. 测试分类:@Category注解可以将测试分为不同的类别,方便按需执行。 3. 参数化测试:@...