Windows 10 操作系统, C,C++,C#、Java或Python语言开发环境(IDE)。
设计型
认识黑盒测试方法中因果图测试方法原理
掌握黑盒测试方法中因果图测试方法过程
问题描述:三角形问题接受三个整数,a、b和c作为输入,用作三角形的边。程序的输出是由这三条边确定的三角形类型:等边三角形、等腰三角形、不等边三角形或非三角形。
作为输入:三角形的三条边必须满足如下条件:
C1:1<=a<=100
C2:1<=b<=100
C3:1<=c<=100
C4:a<b+c
C5:b<a+c
C6:c<a+b
当输入第一个字符是‘#’或者是‘’,第二个输入字符是数字时,文档将被修改;如果第一个字符不是‘#’或‘’,则输出消息N,如果第二个输入字符不是数字,则输出消息M。
要求学生能够理解因果图测试方法的相关概念、方法和过程。
每组二到四人,根据实验题目编写出对应的c语言或c++语言程序,组间相互交换程序,按黑盒测试的方法进行测试。
预习相关课堂和实验内容,了解测试对象。
编写实验材料源代码。
在调试过程中,如果需要,就建立一个或多个桩模块,并建立一个驱动模块。
设计测试用例。
测试。
填写试验报告。
本次软件测试过程当中,使用了JUnit框架,将相关的测试数据保存在csv数据文件当中,通过对csv数据文件读取测试用例来进行测试,方便我们修改测试用例,而且可以降低代码的复杂度、提高代码的可读性。
三角形问题程序流程:
消息输出问题程序流程:
三角形问题:
因果图因果及中间结果说明:
C1:1<=a<=100
C2:1<=b<=100
C3:1<=c<=100
C4:a<b+c
C5:b<a+c
C6:c<a+b
C7:a=b
C8:a=c
C9:b=c
M1:三边输入合法
M2:C4-C6成立
M3:构成三角形
M4:三边相等
M5:三边都不相等
E1:等边三角形
E2:等腰三角形
E3:不等边三角形
E4:非三角形
E5:不可能
因果图:
决策表:
1-256 | 257-384 | 385-448 | 449-480 | 481-496 | 497-504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
因 | C1 | F | T | T | T | T | T | T | T | T | T | T | T | T | T |
C2 | - | F | T | T | T | T | T | T | T | T | T | T | T | T | |
C3 | - | - | F | T | T | T | T | T | T | T | T | T | T | T | |
C4 | - | - | - | F | T | T | T | T | T | T | T | T | T | T | |
C5 | - | - | - | - | F | T | T | T | T | T | T | T | T | T | |
C6 | - | - | - | - | - | F | T | T | T | T | T | T | T | T | |
C7 | - | - | - | - | - | - | T | T | T | T | F | F | F | F | |
C8 | - | - | - | - | - | - | T | T | F | F | T | T | F | F | |
C9 | - | - | - | - | - | - | T | F | T | F | T | F | T | F | |
中间结果 | M1 | F | F | F | T | T | T | T | T | T | T | T | T | T | T |
M2 | - | - | - | F | F | F | T | T | T | T | T | T | T | T | |
M3 | - | - | - | - | - | - | T | T | T | T | T | T | T | T | |
M4 | - | - | - | - | - | - | T | F | F | F | F | F | F | F | |
M5 | - | - | - | - | - | - | F | F | F | F | F | F | F | T | |
果 | E1 | √ | |||||||||||||
E2 | √ | √ | √ | ||||||||||||
E3 | √ | ||||||||||||||
E4 | √ | √ | √ | √ | √ | √ | |||||||||
E5 | √ | √ | √ |
测试用例:
用例编号 | A | B | C | 预期输出 |
---|---|---|---|---|
1 | 0 | 50 | 50 | 非三角形 |
2 | 50 | 0 | 50 | 非三角形 |
3 | 50 | 50 | 0 | 非三角形 |
4 | 50 | 25 | 25 | 非三角形 |
5 | 25 | 50 | 25 | 非三角形 |
6 | 25 | 25 | 50 | 非三角形 |
7 | 50 | 50 | 50 | 等边三角形 |
8 | ? | ? | ? | 不可能 |
9 | ? | ? | ? | 不可能 |
10 | 50 | 50 | 25 | 等腰三角形 |
11 | ? | ? | ? | 不可能 |
12 | 25 | 50 | 50 | 等腰三角形 |
13 | 50 | 25 | 50 | 等腰三角形 |
14 | 30 | 40 | 50 | 不等边三角形 |
消息输出问题:
因果图因果及中间结果说明:
C1:第一位输入“#”
C2:第一位输入“”
C3:第二位输入数字
E1:文档被修改
E2:输出N
E3:输出M
因果图:
决策表:
1-2 | 3 | 4 | 5 | 6 | 7 | 8 | ||
---|---|---|---|---|---|---|---|---|
因 | C1 | T | T | T | F | F | F | F |
C2 | T | F | F | T | T | F | F | |
C3 | - | T | F | T | F | T | F | |
果 | E1 | √ | √ | |||||
E2 | √ | √ | ||||||
E3 | √ | √ |
测试用例:
用例编号 | 输入 | 预期输出 |
---|---|---|
1 | #5 | 文档被修改 |
2 | #n | 输出M |
3 | 5 | 文档被修改 |
4 | n | 输出M |
5 | &5 | 输出N |
6 | &n | 输出N |
【测试结果及分析】
三角形问题实验结果:
关于结果的分析,在本次实验中,所有输入数据中存在非数字类型的测试用例都会输出“不可能”的结果;所有不能构成三角形问题的用例都会输出“非三角形”;其余所有能够成三角形的都会被程序判断并输出其类型。
本实验中,首次使用了因果图方法来解决三角形问题,在实验过程中,对该方法有了相对粗浅的了解。相较于之前所学的三种黑盒而言,使用该方法的所投入的时间要多许多。在分析完因果关系之后,需得画出因果图,进而再列出对应的决策表,毫无疑问,这种测试方法的工作量要远大于单纯的使用决策表方法来进行测试,但可以明确感受到的是该方法可以帮助深入理解并把握输入和输出之间的因果关系,对测试人员的要求较高。尤其是画出该问题的因果图时,能明显地感觉到其巨大的工作量。
消息输出问题实验结果:
由于输入的变量只有两种,输出的结果也只有三种,输入与输出之间的因果关系比较简单清晰,使得本问题的逻辑结构都趋向于简单,因果图较三角形问题而言也比较简洁。当输入第一个字符是‘#’或者是‘’并且第二个输入字符是数字时,文档将被修改;如果第一个字符不是‘#’或‘’,不管第二个字符输出什么,都输出消息N;如果第二个输入字符不是数字,则输出消息M。本着结果之间只有屏蔽关系这一原则,默认第三种情况是在输入的第一位字符为有效输入字符的情况下发生的。
【实验总结】
本实验的难度较之前的三次更大,而且需要测试人员投入比之前更多的时间和精力。
通过本实验,能够明显地感觉到因果图法的优缺点。首先,为了画出一个正确的因果图,测试人员必须对输入情况之间的制约关系以及输入情况之间的各自功能有着明确的认知,有时还能通过这一过程查找出规格说明当中可能存在的漏洞和歧义。
但其缺点也是极其明显的,对于一个具体的问题,其输入和输出的关系是比较容易把握的,但当呈现在面前的是一份需求说明书时,输入和输出之间的因果关系就变得模糊了。其次,当因果关系变得非常庞大时,基于因果图的测试用例太多,并且会给软件测试尤其是手工测试带来承重的负担。
【附-程序源码】
三角形问题源码:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import java.util.Objects;
/**
* @author MaxBrooks chentingxian195467@163.com
* @version 2022/10/25 19:47
* @since JDK17
*/
class TriangleTest {
/**
* 判断是否是数字
* @param a 参数a
* @param b 参数b
* @param c 参数c
* @return boolean
*/
static boolean isNumerical(String a, String b, String c){
return !Objects.equals(a, "?") && !Objects.equals(b, "?") && !Objects.equals(c, "?");
}
/**
* 判断是否输入数据是否合法,若合法,返回true,反之返回false
* @param a 边1
* @param b 边2
* @param c 边3
* @return 返回判断值
*/
static boolean isDataUseful(Integer a, Integer b,Integer c){
return (a >= 1 && a <= 100) && (b >= 1 && b <= 100) && (c >= 1 && c <= 100);
}
/**
* 判断输入数据能否构成三角形,若能,返回true,反之返回false
* @param a 边1
* @param b 边2
* @param c 边3
* @return 返回判断值
*/
static boolean isTriangle(Integer a, Integer b,Integer c){
return !(a + b <= c) && !(b + c <= a) && !(a + c <= b);
}
/**
* 判断三角形类型
* @param a 边1
* @param b 边2
* @param c 边3
*/
static void kindOfTriangle(Integer a, Integer b, Integer c){
if (a.equals(b) || b.equals(c) || a.equals(c)){
if (a.equals(b) && b.equals(c)) //没必要再添一句a.equals(c),因为前两者的可以推导出a == c的结论
System.out.println("等边三角形");
else
System.out.println("等腰三角形");
}else
System.out.println("不等边三角形");
}
@ParameterizedTest
@CsvFileSource(resources = "/softwarequalityandtest/DecisionTable/trianglesForDT.csv")
void isTriangle02(String a, String b,String c){
System.out.println("***************************");
System.out.printf("%3s %3s %3s ",a,b,c);
if (isNumerical(a, b, c)){
Integer x = Integer.valueOf(a);
Integer y = Integer.valueOf(b);
Integer z = Integer.valueOf(c);
if (isDataUseful(x, y, z)){
if (isTriangle(x, y, z)){
kindOfTriangle(x, y, z);
}else
System.out.println("非三角形");
}else {
System.out.println("非三角形");
}
}else
System.out.println("不可能");
}
}
消息输出问题源码:
package com.example.java.classworkin2022.softwarequalityandtest.experiments.exp01_BoundaryValueAnalysis;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 消息输出问题 实验四
*
* @author MaxBrooks chentingxian195467@163.com
* @version 2022/11/30 23:48
* @since JDK17
*/
public class MessageOutputs {
/**
* 判断输入字符是否为数字
* @param str 带监测字符串
* @return 若为数字,返回true,反之返回false
*/
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*#");
Matcher isNum = pattern.matcher(str);
if (! isNum.matches()){
return false;
}
return true;
}
@ParameterizedTest
@CsvFileSource(resources = "/softwarequalityandtest/CausalityDiagram/MessageOutput.csv")
void messageOutput(String a, String b){
if (a.equals("*") || a.equals("#")){
if (isNumeric(b)){
System.out.println("************************************");
System.out.printf(a + " " + b + " " + "文档被修改\n");
}else {
System.out.println("************************************");
System.out.printf(a + " " + b + " " + "M\n");
}
}else {
System.out.println("************************************");
System.out.printf(a + " " + b + " " + "N\n");
}
}
}