第二次作业及参考答案

第一题

在一个客户信息查询界面中,输入条件有“姓名”、“身份证号”、“手机”,采用正交表方式设计该界面查询功能的测试用例。

答:

针对本测试有3个输入条件,每个输入有2种取值情况,可以选择L₄(2³)正交表,其正交表值如下表所示:

实验数\列号 姓名 身份证号 手机
1 1 1 1
2 1 0 0
3 0 1 0
4 0 0 1

测试用例:

测试用例/查询条件 姓名 身份证号 手机
测试用例1 填写 填写 填写
测试用例2 填写
测试用例3 填写
测试用例4 填写

第二题

根据如下图所示的程序流程图,分别使用语句覆盖测试、判定覆盖测试、条件覆盖测试和路径覆盖测试进行测试用例设计。

答:

1)语句覆盖

设计测试用例,使得被测试程序中的每条可执行语句至少被执行一次。其测试用例表如下所示。

用例序号 输入数据 预期输出 覆盖语句
1 (X,Y)=(1,11) (X,Y)=(1,11) X>0 AND Y>10;Y=Y/X;X<-10 OR Y<0
2 (X,Y)=(0,-1) (X,Y)=(0,1) X>0 AND Y>10;X<-10 OR Y<0;Y=-(Y+X)

2)判定覆盖

设计测试用例,使得被测试程序中的每个判断的”真”、”假”分支至少被执行一次。设X>0 AND Y>10为判定条件M,X<-10 OR Y<0为判定条件N。
设计的判定覆盖测试用例如下表所示。

用例序号 输入数据 预期输出 覆盖判定条件
1 (X,Y)=(1,11) (X,Y)=(1,11) M为真,N为假
2 (X,Y)=(0,-1) (X,Y)=(0,1) M为假,N为真

3)条件覆盖

设计测试用例,使得被测试程序中分支判断语句中每个条件的可能值至少被满足一次。

条件X>0:
取真时为T1,取假时为F1
条件Y>10:
取真时为T2,取假时为F2
条件x<-10:
取真时为T3,取假时为F3
条件Y<0:
取真时为T4,取假时为 F4

设计的条件覆盖测试用例如下表所示。

用例序号 输入数据 预期输出 覆盖条件
1 (X,Y)=(1,-1) (X,Y)=(1,0) T1,F2,F3,T4
2 (X,Y)=(-11,11) (X,Y)=(-11,0) F1,T2,T3,F4

4)基本路径覆盖

设计测试用例,使得被测试程序中的基本路径至少被覆盖一次。依据该程序控制流图计算环路复杂度=3(判断节点数目+1),因此,该程序的基本路径有3条。

设计的基本路径覆盖测试用例如下表所示

用例序号 输入数据 预期输出 覆盖路径
1 (X,Y)=(0,0) (X,Y)=(0,0) ace
2 (X,Y)=(1,11) (X,Y)=(1,11) abce
3 (X,Y)=(-11,1) (X,Y)=(-11,10) acde
4 不存在 不存在 abcde

但是看这篇文章 软件测试——程序控制流图,McCabe环形复杂度_根据程序画出控制流图_Dic0k的博客-CSDN博客,按照它的逻辑,环形复杂度应该有5条。(很奇怪)

第三题

针对如下样本程序,分析该程序逻辑覆盖测试方法中的语句覆盖、判定覆盖、条件覆盖和基本路径覆盖,并说明哪种方法覆盖率高?为什么?

被测样本程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;
public class Coverage {
public static void main(String[] args){
System.out.println("start main function:path a...");
int A=0,B=0,X=0;
Scanner s = new Scanner(System.in);
System.out.println("输入A:"); A = s.nextInt();
System.out.println("输入B="); B = s.nextInt();
System.out.println("输入X="); X = s.nextInt();
s.close();
if (A>1 && B==0) {
X=X/A;
System.out.println("path c");
} else {
System.out.println("path b"); }
if (A==2 || X>1) {
X=X+1;
System.out.println("path e");
} else {
System.out.println("path d"); }
System.out.println("end main function.");
}
}

​ 答:

注:以下答案只参考了标准答案的一部分

VF1D1EJ2__LKYS_1_GPGJ5W.png

  1. 语句覆盖测试

    用例序号 输入数据 预期输出 覆盖路径
    1 (A,B,X)=(2,0,2) start main function:path a…,输入A:,输入B=,输入X=,path c,path e,end main function. ace
    2 (A,B,X)=(0,1,1) start main function:path a…,输入A:,输入B=,输入X=,path b,path d,end main function. abd
  2. 判定覆盖测试

    用例序号 输入数据 预期输出 覆盖路径
    1 (A,B,X)=(2,0,2) start main function:path a…,输入A:,输入B=,输入X=,path c,path e,end main function. ace
    2 (A,B,X)=(0,1,1) start main function:path a…,输入A:,输入B=,输入X=,path b,path d,end main function. abd
  3. 条件覆盖测试

    用例序号 输入数据 预期输出 覆盖路径
    1 (A,B,X)=(2,0,2) start main function:path a…,输入A:,输入B=,输入X=,path c,path e,end main function. ace
    2 (A,B,X)=(0,1,1) start main function:path a…,输入A:,输入B=,输入X=,path b,path d,end main function. abd
  4. 基本路径覆盖测试

    用例序号 输入数据 预期输出 覆盖路径
    1 (A,B,X)=(2,0,2) start main function:path a…,输入A:,输入B=,输入X=,path c,path e,end main function. ace
    2 (A,B,X)=(0,1,1) start main function:path a…,输入A:,输入B=,输入X=,path b,path d,end main function. abd
    3 (A,B,X)=(0,1,2) start main function:path a…,输入A:,输入B=,输入X=,path b,path e,end main function. abe

综上所述,基本路径覆盖测试用的测试用例最多,覆盖的路径也最多,故基本路径覆盖的覆盖率最高。

注:环形复杂度必定是基本路径个数的上限。

Snipaste_2023-05-31_21-48-19.png

第四题

使用PMD代码分析工具针对如下被测程序,找出该程序存在的潜在缺陷,给出结果界面截图,并说明各个缺陷出现的原因。

被测样本程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
public class Coverage {
public static void main(String[] args){
System.out.println("start main function:path a...");
int A=0,B=0,X=0;
Scanner s = new Scanner(System.in);
System.out.println("输入A:"); A = s.nextInt();
System.out.println("输入B="); B = s.nextInt();
System.out.println("输入X="); X = s.nextInt();
s.close();
if (A>1 && B==0) {
X=X/A;
System.out.println("path c");
} else {
System.out.println("path b"); }
if (A==2 || X>1) {
X=X+1;
System.out.println("path e");
} else {
System.out.println("path d"); }
System.out.println("end main function.");
}

答:

注:以下答案只参考了标准答案的一部分

Z__LBIY38___C`L5GCFZSVF.jpg

以下是可能的缺陷(感觉每个人做出来都不一样哈哈哈哈😆):

(1)VariableNamingConventions:

​ ①变量应以小写字符开头,’A’’B’’X’均以大写字符开头

(2)UseUtilityClass:

​ ①所有方法都是静态的,可以考虑使用实用工具类,或添加一个私 有构造函数,或使类抽象来屏蔽这个警告

(3)LocalVariableCouldBeFinal:

​ ①局部变量’s’可以声明为final

(4)LocalVaraiableNamingConventions:

​ ①局部变量名’A’’B’’X’不匹配’[a-z][a-zA-Z0-9]*’

(5)MethodArgumentCouldBeFinal:

​ ①参数’args’未赋值,可以声明为final

(6)CommentRequired:

​ ①类注释是必需的

​ ②公共方法和构造函数的注释是必需的

(7)OneDeclarationPerLine:

​ ①int A=0,B=0,X=0; 每个声明为一行,可以增强代码的可读性

(8)UnusedAssignment:

​ ①变量’B’的初始化式从未使用(后被重写)

​ ②变量’A’的初始化式从未使用(后被覆盖)

​ ③变量’X’的初始化式从未使用(后被覆盖)

​ ④ X=X+1; 赋给变量’X’的值从未使用过

(9)SystemPrintln:

​ ①使用System.out.println

(10)ShortVariable:

​ ① Scanner s = new Scanner(System.in); 避免使用像s这样名字较 短的变量

​ ②避免使用短名称的变量:如A,B,X

(11)DataflowAnomalyAnalysis:

​ ①发现变量’A’的’DD’异常

​ int A=0,B=0,X=0;

​ Scanner s = new Scanner(System.in);

​ System.out.println(“输入A:”);A = s.nextInt();

​ ②发现变量’X’的’DU’异常

​ X=X+1;

​ System.out.println(“path e”);

​ } else {

​ System.out.println(“path d”); }

​ System.out.println(“end main function.”);

​ }

​ ③发现变量’X’的’DD’异常

​ int A=0,B=0,X=0;

​ Scanner s = new Scanner(System.in);

​ System.out.println(“输入A:”); A = s.nextInt();

​ System.out.println(“输入B=”); B = s.nextInt();

​ System.out.println(“输入X=”); X = s.nextInt();

​ ④发现变量’B’的’DD’异常

​ int A=0,B=0,X=0;

​ Scanner s = new Scanner(System.in);

​ System.out.println(“输入A:”); A = s.nextInt();

​ System.out.println(“输入B=”); B = s.nextInt();

(12)CloseResource:

​ ①Scanner s = new Scanner(System.in); 确保像InputStream对象 这样的资源在使用后被关闭

我感觉第四题应该不会考🙂

声明:除特殊标注外(综合考虑其他同学的答案),答案均为老师原版答案