软件测试技术实验报告
--------实验一:单元测试
学
班
姓
学
院:计算机学院
级:软件
名:
号:
实验目的:
(1) 掌握白盒测试方法,并按单元测试的要求设计测试用例。
(2) 能熟练应用 junit 测试工具进行单元测试;
(3) 进行代码覆盖检查。
实验原理:
一、 逻辑覆盖
结构性测试力求提高测试覆盖率。逻辑覆盖是对一系列测试过程的总称,它是在使用白
盒测试法时,选用测试用例执行程序逻辑路径的方法。
逻辑覆盖按覆盖程度由低到高大致分为以下几类:
(1) 语句覆盖:设计若干测试用例,使程序中每一可执行语句至少执行一次;
(2) 判断覆盖:设计用例,使程序中的每个逻辑判断的取真取假分支至少经历一次;
(3) 条件覆盖:设计用例,使判断中的每个条件的可能取值至少满足一次;
(4) 判断/条件覆盖:设计用例,使得判断中的每个条件的所有可能结果至少出现一
次,而且判断本身所有可能结果也至少出现一次;
(5) 条件组合覆盖。设计用例,使得每个判断表达式中条件的各种可能组合都至少
出现一次;显然,满足⑤的测试用例也一定是满足②、③、④的测试用例。
(6) 路径覆盖。设计足够的测试用例,使程序的每条可能路径都至少执行一次。
如果把路径覆盖和条件组合覆盖结合起来,可以设计出检错能力更强的测试数据用例。
二、 基本路径测试
如果把覆盖的路径数压缩到一定限度内,例如,程序中的循环体只执行零次和一次,就
成为基本路径测试。它是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出
基本可执行路径集合,从而设计测试用例的方法。
设计出的测试用例要保证在测试中,程序的每一个可执行语句至少要执行一次。
① 程序的控制流图
控制流图是描述程序控制流的一种图示方法。基本控制构造的图形符号如图所示。符号
○称为控制流图的一个结点,一组顺序处理框可以映射为一个单一的结点。控制流图中的箭
头称为边,它表示了控制流的方向,在选择或多分支结构中分支的汇聚处,即使没有执行语
句也应该有一个汇聚结点。边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域
也应记为一个区域。
图 3-1 控制流图的各种图形符号
如果判定中的条件表达式是复合条件时,即条件表达式是由一个或多个逻辑运算符
(OR,AND,NAND,NOR)连接的逻辑表达式,则需要改复合条件的判定为一系列只有
单个条件的嵌套的判定。例如对应图 3-2. (a) 的复合条件的判定,应该画成如图 3-2. (b) 所
示的控制流图。 条件语句 if a OR b 中条件 a 和条件 b 各有一个只有单个条件的判定结点。
图 3-2 复合逻辑下的控制流图
② 计算程序环路复杂性
进行程序的基本路径测试时,程序的环路复杂性给出了程序基本路径集合中的独立路径
条数,这是确保程序中每个可执行语句至少执行一次所必需的测试用例数目的上界。
所谓独立路径,是指包括一组以前没有处理的语句或条件的一条路径。如在图 3-3(b)
所示的控制流图中,一组独立的路径是:
path1:1 - 11
path2:1 - 2 - 3 - 4 - 5 - 10 - 1 - 11
path3:1 - 2 - 3 - 6 - 8 - 9 - 10 - 1 - 11
path4:1 - 2 - 3 - 6 - 7 - 9 - 10 - 1 - 11
路径 path1,path2,path3,path4 组成了图 3-3 (b) 所示控制流图的一个基本路径集。只
要设计出的测试用例能够确保这些基本路径的执行,就可以使得程序中的每个可执行语句至
少执行一次,每个条件的取真分支和取假分支也能得到测试。基本路径集不是唯一的,对于
给定的控制流图,可以得到不同的基本路径集。
(a) 程序流程图
(b) 控制流图
图 3-3 程序流程图与对应的控制流图
通常环路复杂性可用以下三种方法求得。
将环路复杂性定义为控制流图中的区域数。
设 E 为控制流图的边数,N 为图的结点数,则定义环路复杂性为 V(G)=E-N+2。
若设 P 为控制流图中的判定结点数,则有 V(G)=P+1。
因为图 5.14(b)所示控制流图有 4 个区域。其环路复杂性为 4。 它是构成基本路径集的
独立路径数的上界。可以据此得到应该设计的测试用例的数目。
③ 导出测试用例
利用逻辑覆盖方法生成测试用例,确保基本路径集中每条路径的执行。
三、 单元测试的步骤
通常单元测试在编码阶段进行。在源程序代码编制完成,经过评审和验证,确认没有
语法错误之后,就开始进行单元测试的测试用例设计。利用设计文档,设计可以验证程序功
能、找出程序错误的多个测试用例。对于每一组输入,应有预期的正确结果。
模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一
些辅助模块去模拟与被测模块相联系的其它模块。这些辅助模块分为两种:
(1)驱动模块:相当于被测模块的主程序。它接收测试数据,把这些数据传送给被测
模块,最后输出实测结果。
(2)桩模块:用以代替被测模块调用的子模块。桩模块可以做少量的数据操作,不需
要把子模块所有功能都带进来,但不允许什么事情也不做。
被测模块、与它相关的驱动模块及桩模块共同构成了一个“测试环境”,如图 3-1 所
示。
实验内容:
1、用 java 语言编写一个求一元二次方程根的函数
2、设计白盒测试用例,达到分支覆盖
3、使用弱健壮等价类分析方法设计测试用例。
2、根据以上设计的测试用例,编写 junit 测试代码,并进行测试。
实验步骤:
(1)根据白盒法设计测试用例,并撰写单元测试计划书;
(2)根据每个测试用例,编写基本 Junit 的单元测试脚本;
(3)生成代码覆盖测试报告;
实验结果:
测试用例:
(1) 方程两不同实数根测试用例:
测试用例 ID
Equaltion1
测试用例名称
方程的解
测试目的
验证方程两不同实数根的正确性
前置条件
a!=0&&b*b-4*a*c>0
操作步骤与输入 a=2,b=5,c=2
预期结果
实际结果
x1=-0.5,x2=-2.0
x1=-0.5,x2=-2.0
(2) 方程相同实数根测试用例:
测试用例 ID
Equaltion1
测试用例名称
方程的解
测试目的
验证方程相同实数根的正确性
前置条件
a!=0&&b*b-4*a*c==0
操作步骤与输入 a=1,b=2,c=1
预期结果
实际结果
x1=x2=-1
x1=x2=-1
(1) 方程两虚数根测试用例:
测试用例 ID
Equaltion1
测试用例名称
方程的解
测试目的
方程两不同实数根的正确性
前置条件
a!=0&&b*b-4*a*c<0
操作步骤与输入 a=1,b=1,c=1
预期结果
实际结果
x1=-0.5+0.87i,x2=-0.5-0.87i
x1=-0.5+0.87i,x2=-0.5-0.87i
实验代码
(1)源代码:
public class Yiyuan {
private double a, b, c;
double[] ary=new double[2];
public Yiyuan(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
public static void main(String[] args)
{
double[] results = new Yiyuan(1, -1, -40).analyze();
}
public double[] analyze() {
double delt = b * b - 4 * a * c;
if (delt < 0) {
System.out.print("无实根");
return null;
}
else if (delt == 0) {
}
else {
ary[0]=ary[1] = -b / (2 * a) ;
System.out.print("x1="+ary[0]+" x2="+ary[1]);
ary[0] = (-b + Math.sqrt(delt)) / (2 * a);
ary[1] = (-b - Math.sqrt(delt)) / (2 * a);
System.out.print("x1="+ary[0]+" x2="+ary[1]);
}
return ary;
}
}
(2)测试代码:
import org.junit.Assert;
import org.junit.Test;
public class YiyuanTest {
private Yiyuan y;
@Test
public void testAnalyze() {
y=new Yiyuan(1,2,1);
double result[]={-1.0,-1.0};
Assert.assertArrayEquals(result, y.analyze(), 0);
}
}
实验配图
1. 方程两不同实数根测试
2. 方程相同实数根测试
3. 方程两虚数根测试
实验小结与心得:
这次上机让我简单的熟悉了程序测试,了解到测试对代码的完成的重要性。这次实验
要求用java编写一元二次方程,因为对java不熟悉,在老师和同学的指导下,搭配好了环境,
在编写代码完成过后,在导入测试junit的时候遇到了问题,经指导,顺利完成本次试验。这
次实验让我知道了必须要掌握一门重要的语言。