一、实验目的
掌握基于覆盖理论与基本路径的基本白盒测试方法和实践
二、实验要求
运用逻辑覆盖测试的覆盖准则设计被测程序的测试用例,并运行测试用例检查程序的正确与否,给出程序缺陷小结。
三、实验内容
根据各位同学自己的被测程序,分别作出各类白盒测试技术的用例设计和相应的Junit脚本。
所有的覆盖的技术:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖,基本路径测试方法。
1) 被测原代码
package Test1;
import java.io.IOException;
import java.util.Scanner;
public class yongjin01 {
public static void main(String[] args){
yongjin01 yj = new yongjin01();
System.out.println("请分别输入三种手机配件的销售情况:");
double headphone = yj.Input(0);
double shell = yj.Input(0);
double protector = yj.Input(0);
System.out.println("耳机数量:"+headphone+"\n手机壳数量:"+shell+" \n手机贴膜数量:"+protector);
double commission = yj.Commission(headphone, shell, protector);
System.out.println("销售佣金:"+commission);
}
public double Input(double number){
double num = 0;
Scanner scanner = new Scanner(System.in);
try{
if(num<0){
System.out.println("输入的数量不满足要求!");
}else{
num = scanner.nextDouble();
return num;
}
}catch(Exception e){System.out.println("输入不合法!");}
return num;
}
public double Commission(double headphone,double shell,double protector){
double commission = 0; //定义佣金;
double headphonePrice = 80;
double shellPrice = 10;
double protectorPrice = 8;
double headphonesales = headphonePrice*headphone;
double shellsales = shellPrice*shell;
double protectorsales = protectorPrice*protector;
double sales = headphonesales+shellsales+protectorsales;
if(sales>1800){
commission = 0.10*1000;
commission = commission+0.15*800;
commission = commission+0.20*(sales-1800);
}else if(sales>1000){
commission = 0.10*1000;
commission = commission+0.15*(sales-1000);
}
else
commission = 0.10*sales;
return commission;
}
}
2)依据覆盖技术,测试用例列表:
DD-路径图
<1>语句覆盖
编号 | 输入 | 预期输出 | 实际输出 | 执行路径 | 是否通过 |
1 | 10 101 0 | 222.0 | 222.0 | ABF | √ |
2 | 10 100 0 | 220.0 | 220.0 | ACDF | √ |
3 | 0 100 0 | 100.0 | 100.0 | ACEF | √ |
<2>判定/条件覆盖
编号 | 输入 | 预期输出 | 实际输出 | 执行路径 | 是否通过 |
1 | 10 101 0 | 222.0 | 222.0 | ABF | √ |
2 | 10 100 0 | 220.0 | 220.0 | ACDF | √ |
3 | 0 100 0 | 100.0 | 100.0 | ACEF | √ |
4 | 1 100 0 | 112.0 | 112.0 | ACDF | √ |
5 | 1 1 1 | 9.8 | 9.8 | ACEF | √ |
6 | -1 -1 -1 | 错误提示 | -9.8 | ACEF | × |
<3>组合覆盖
编号 | 输入 | 预期输出 | 实际输出 | 执行路径 | 是否通过 |
1 | 10 101 0 | 222.0 | 222.0 | ABF | √ |
2 | 10 100 0 | 220.0 | 220.0 | ACDF | √ |
3 | 0 100 0 | 100.0 | 100.0 | ACEF | √ |
4 | 1 100 0 | 112.0 | 112.0 | ACDF | √ |
5 | 1 1 1 | 9.8 | 9.8 | ACEF | √ |
6 | -1 -1 -1 | 错误提示 | -9.8 | ACEF | × |
7 | 0 0 0 | 0.0 | 0.0 | ACEF | √ |
3)相应Junit测试脚本、执行结果
package test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import daima.yongjin01;
public class CommissionTest {
private yongjin01 yj;
@Before
public void setUp() throws Exception {
yj = new yongjin01();
}
@After
public void tearDown() throws Exception {
}
@Test
public void testCommissionSentence1() {
assertEquals(222.0, yj.Commission(10, 101, 0), 0.00001);
}
@Test
public void testCommissionSentence2() {
assertEquals(220.0, yj.Commission(10, 100, 0), 0.00001);
}
@Test
public void testCommissionSentence3() {
assertEquals(100.0, yj.Commission(0, 100, 0), 0.00001);
}
@Test
public void testCommissionCondition1() {
assertEquals(112.0, yj.Commission(1, 100, 0), 0.00001);
}
@Test
public void testCommissionCondition2() {
assertEquals(9.8, yj.Commission(1, 1, 1), 0.00001);
}
@Test
public void testCommissionCondition3() {
assertEquals(-1, yj.Commission(-1, -1, -1), 0.00001);
}
@Test
public void testCommissionCombination() {
assertEquals(0.0, yj.Commission(0, 0, 0), 0.00001);
}
}
结果:
4)给出测试参数化和打包测试的脚本,并生成执行结果
测试参数化:
package test;
import static org.junit.Assert.*;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import daima.yongjin01;
@RunWith(Parameterized.class)
public class ParameterizedTest {
private double headphone;
private double shell;
private double protector;
private double result;
private yongjin01 yj;
@Parameters
public static Collection data(){
return Arrays.asList(
new Object[][]{
{10, 101, 0, 222.0},
{10, 100, 0, 220.0},
{0, 100, 0, 100.0},
{1, 100, 0, 112.0},
{1, 1, 1, 9.8},
{-1, -1, -1, -1},
{0, 0, 0, 0.0},
}
);
}
public ParameterizedTest (double headphone,double shell,double protector,double result) {
yj=new yongjin01();
this.headphone=headphone;
this.shell=shell;
this.protector=protector;
this.result=result;
}
@Test
public void testCommission(){
assertEquals(result,yj.Commission(headphone, shell, protector), 0.00001);
}
}
结果:
打包测试:
package test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({CommissionTest.class,ParameterizedTest.class})
public class AllCommission {
}
结果:
四、测试小结
(1)测试找到的缺陷清单:
1.输入为-1,-1,-1时结果错误。
(2)对源代码的修改建议 :
1.程序需要对负数的输入能够正确处理,而不是计算值为负数的佣金。
2.程序需要对小数的出入能够正确处理,而不是数量为小数的时候能够照常计算佣金。
3.Commission函数的函数原型应该是String Commission(int headphone,int shell,int protector),这个上课和实验要求都有,希望能改正。
(3)测试总结与心得体会
1.这次测试的这个函数,在画完流程图之后发现,这个程序实际上只有一处判断,这个判断有3个分支,即sales>1800,1800>=sales>1000和sales<=1000三种情况,这样只要满足语句覆盖的测试用例就可以满足条件覆盖、判定覆盖、组合覆盖甚至路径覆盖。而且可以为这3个分支划分3个等价类,再在等价类中各取一个样例做测试用例即可。也就是3个测试用例就可以完成测试。不知道我这样想对不对。。
2.另外,想对程序进行小数和负数的测试,因为看完代码之后很明显这样的测试是通不过的。但是程序又没有这样的判断,写测试用例的时候不知道该写是什么覆盖方法,而且预期输出也不知道该怎么写,应为程序根本没有处理所以也不知道正确情况下程序应该是输出什么,只能是根据常识判断。
3.上完课对Juint的使用熟练了很多。上次实验课Junit的使用并不熟悉,基本上都是上网查了资料才勉强完成的,而这次可以很顺畅地完成实验。