软件测试--应用JUnit进行单元测试

文章目录

    • 一、实验原理
    • 二、实验内容
      • 1、JUnit包下载配置
      • 2、编写JUnit测试用例
    • 三、编写测试代码

一、实验原理

JUnit是一个开源的Java编程语言的单元测试框架,最初由 Erich Gamma 和 Kent Beck 编写。Junit测试是一种白盒测试工具。JUnit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。具有JUnit经验对于应用“测试驱动开发(TDD)”的程序开发模型是非常重要的。
JUnit本质上是一套框架,即开发者制定了一套条条框框,遵循这此条条框框要求编写测试代码,如继承某个类,实现某个接口,就可以用JUnit进行自动测试了。
  由于JUnit相对独立于所编写的代码,可以测试代码的编写可以先于实现代码的编写,XP 中推崇的 test first design的实现有了现成的手段:用JUnit写测试代码,写实现代码,运行测试,测试失败,修改实现代码,再运行测试,直到测试成功。以后对代码的修改和优化,运行测试成功,则修改成功。
Java 下的 team 开发,采用 cvs(版本控制) + ant(项目管理) + JUnit (集成测试) 的模式时,通过对ant的配置,可以很简单地实现测试自动化。

二、实验内容

1、JUnit包下载配置

(1) 从http://www.junit.org或者此资源(提取码:1234)下载Junit。
(2) 解包Junit-4.X,得到如图的解包文件。
软件测试--应用JUnit进行单元测试_第1张图片
Junit文件说明:
junit.jar:JUnit框架结构、扩展和测试运行器的二进制发布
src.jar:JUnit的源代码,包括一个 Ant 的buildfile文件
junit:是个目录,内有JUnit自带的用JUnit编写的测试示例程序
javadoc:JUnit完整的API文档
doc:一些文档和文章,包括“Test Infected: Programmers Love Writing Tests”和其它一些资料,可以帮助我们入门。
(3) 配置。
步骤如下:
①右击“我的电脑”-“属性”-高级-环境变量;
②在系统变量中选择“CLASSPATH”,添加如下变量值:
软件测试--应用JUnit进行单元测试_第2张图片
③检验:打开cmd
输入命令:java org.junit.runner.JUnitCore org.junit.tests.AllTests
配置成功,如图下图所示。
软件测试--应用JUnit进行单元测试_第3张图片

2、编写JUnit测试用例

使用JUnit 的最佳实践:
(1)新建一个名为test的source folder,用于存放测试类源代码;
(2)目标类与测试类应该位于同一个包下面,这样测试类中就不必导入源代码所在的包,因为他们位于同一个包下面;
(3)测试类的命名规则:假如目标类是Calculator,那么测试类应该命名为TestCalculator或者是CalculatorTest。

下面将以一个具体的实例进行说明。
(1) 新建一个 Java Project。命名为JunItTest,然后配置构建路径Add Library-JUnit 4。
在Java Build Path-Libraries上点击Add Library…选择JUnit导入
软件测试--应用JUnit进行单元测试_第4张图片
选择JUnit 4
软件测试--应用JUnit进行单元测试_第5张图片
(2) 建一个包com.test 并在此包下建一个除法类:Divide。
软件测试--应用JUnit进行单元测试_第6张图片
Divide类的程序源代码如下所示:

package com.test;
public class Divide {
	private static int result;
	public void divide(int num)
	{
		result/=num;
	}
	public int getResult()
	{
		return result;
	}
	public void setResult(int result)
	{
		Divide.result=result;
	}
}

(3)右键Divide类,新建JUnit Test Case
软件测试--应用JUnit进行单元测试_第7张图片
软件测试--应用JUnit进行单元测试_第8张图片
软件测试--应用JUnit进行单元测试_第9张图片
Eclipse会自动为测试类取名:被测试类+Test,单击Next就可以了。选择需要进行测试的方法。
注意:测试类之所以使用“Test”开头或“Test”结尾,是为了更好的区分测试类与被测试类。
软件测试--应用JUnit进行单元测试_第10张图片
(4)创建测试用例。首先创建一个默认的测试用例。
软件测试--应用JUnit进行单元测试_第11张图片
执行测试用例。如图所示。软件测试--应用JUnit进行单元测试_第12张图片
测试结果:红色,测试失败。
软件测试--应用JUnit进行单元测试_第13张图片
(5)修改测试用例:DivideTest.java。具体代码如下所示。

package com.test;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class DivideTest {
	private static Divide div=new Divide();
	@Before
	public void init()
	{
		div.setResult(10);
	}
	@Test
	public void testDivide() {
		div.divide(10);
		assertEquals(1, div.getResult());
	}
	@Test(expected=Exception.class)
	public final void dividezero()
	{
		div.divide(0);
	}
}

注意:测试方法必须使用注解 org.junit.Test 修饰。 测试方法必须使用 public void 修饰,而且不能带有任何参数。测试方法在JUnit4.X中没有要求,但是为了使得命名意义,一般推荐采用“test”+“被测试方法”的命名规则。assertEquals 是由 JUnit 提供的一系列判断测试结果是否正确的静态断言方法(位于类 org.junit.Assert 中)之一,我们使用它将执行结果 result 和预期值“result”进行比较,来判断测试是否成功。

新测试用例运行后的测试结果如下图所示图所示。
软件测试--应用JUnit进行单元测试_第14张图片
绿色的进度条提示我们,测试运行通过了。但现在就宣布代码通过了单元测试还为时过早。记住:你的单元测试代码不是用来证明你是对的,而是为了证明你没有错。因此单元测试的范围要全面,比如对边界值、正常值、错误值得测试;对代码可能出现的问题要全面预测,而这也正是需求分析、详细设计环节中要考虑的。

三、编写测试代码

(1)应用JUnit对类WordDealUtil编写测试代码
被测试程序说明:对名称、地址等字符串格式的内容进行格式检查。将Java对象名称(每个单词的头字母大写)按照数据库命名的习惯进行格式化格式化后的数据为小写字母,并且使用下划线分割命名单词。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 对名称、地址等字符串格式的内容进行格式检查
 * 或者格式化的工具类
 */
public class WordDealUtil {
	/**
	 * 将Java对象名称(每个单词的头字母大写)按照
	 * 数据库命名的习惯进行格式化
	 * 格式化后的数据为小写字母,并且使用下划线分割命名单词
	 * 例如:employeeInfo 经过格式化之后变为 employee_info
	 * @param name	Java对象名称
	 */
	public static String wordFormat4DB(String name){
		Pattern p = Pattern.compile("[A-Z]");
		Matcher m = p.matcher(name);
StringBuffer sb = new StringBuffer();		
		while(m.find()){
			m.appendReplacement(sb, "_"+m.group());
		}
		return m.appendTail(sb).toString().toLowerCase();
	}
}

(2)添加测试代码。

import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TestWordDealUtil {
	//测试wordFormat4DB正常运行的情况
	@Test public void wordFormat4DBNormal(){
		String target = "employeeInfo";
		String result = WordDealUtil.wordFormat4DB(target);		
		assertEquals("employee_info", result);
	}
}

推荐每编写完一个测试方法,则执行”run”
看测试结果,测试结果通过:
软件测试--应用JUnit进行单元测试_第15张图片
(3)继续添加测试代码,并运行看测试结果。

public class TestWordDealUtil {	
	//测试 null 时的处理情况
	@Test public void wordFormat4DBNull(){
		String target = null;
		String result = WordDealUtil.wordFormat4DB(target);		
		assertNull(result);
	}	
	//测试空字符串的处理情况
	@Test public void wordFormat4DBEmpty(){
		String target = "";
		String result = WordDealUtil.wordFormat4DB(target);		
		assertEquals("", result);
	}
	//测试当首字母大写时的情况
	@Test public void wordFormat4DBegin(){
		String target = "EmployeeInfo";
		String result = WordDealUtil.wordFormat4DB(target);
		assertEquals("employee_info", result);
	}	
	//测试当尾字母为大写时的情况
	@Test public void wordFormat4DBEnd(){
		String target = "employeeInfoA";
		String result = WordDealUtil.wordFormat4DB(target);
		assertEquals("employee_info_a", result);
	}
//测试多个相连字母大写时的情况
	@Test public void wordFormat4DBTogether(){
		String target = "employeeAInfo";
		String result = WordDealUtil.wordFormat4DB(target);  
		assertEquals("employee_a_info", result);
	}
}

(4)分析测试结果
软件测试--应用JUnit进行单元测试_第16张图片
测试 null 时的处理情况与测试当首字母大写时的情况出现问题,需要修改源代码
(6)修改代码为:

public class WordDealUtil {
	public static String wordFormat4DB(String name){
		if(name == null){
	       return null;
		}
		Pattern p = Pattern.compile("[A-Z]");
		Matcher m = p.matcher(name);
        StringBuffer sb = new StringBuffer();		
		while(m.find()){
			if(m.start() != 0)
			    m.appendReplacement(sb, "_"+m.group());
		}
		return m.appendTail(sb).toString().toLowerCase();
	}
}

测试结果:
软件测试--应用JUnit进行单元测试_第17张图片
至此,现在的代码已经比较稳定。

你可能感兴趣的:(单元测试)