第二次实验报告:结构性测试
被测试代码链接:
一、实验目的
掌握基于覆盖理论与基本路径的基本白盒测试方法和实践
二、实验要求
运用逻辑覆盖测试的覆盖准则设计被测程序的测试用例,并运行测试用例检查程序的正确与否,给出程序缺陷小结。
三、实验内容
根据各位同学自己的被测程序,分别作出各类白盒测试技术的用例设计和相应的Junit脚本。
所有的覆盖的技术:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖,基本路径测试方法。
包括的内容有:
1) 被测原代码
package test1; import java.util.Scanner; public class Yongjin01 { 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; } public static void main(String[] args) { while(true){ Yongjin01 yj = new Yongjin01(); System.out.println("请分别输入三种手机配件的销售情况:"); double headphone = yj.Input(0); double shell = yj.Input(0); double protector = yj.Input(0); while(headphone<0||shell<0||protector<0){ System.out.println("输入必须大于等于0,请重输!"); return; } System.out.println("耳机数量:" + headphone + "\n手机壳数量:" + shell + " \n手机贴膜数量:" + protector); double commission = yj.Commission(headphone, shell, protector); System.out.println("销售佣金:" + commission); } } }
2)依据覆盖技术,测试用例列表:
DD-路径图:
A=SALES,B>1800,C<1800,1000<D<=1800,E<=1000,F=COMMISSION.
覆盖方法 | 用例号 | 输入 | 期待结果 | 实际结果 | 执行路径 | 通过 |
语句覆盖 | 1 | 10 102 0 | 224 | 224 | ABF | √ |
语句覆盖 | 2 | 10 100 0 | 220 | 220 | ACDF | √ |
语句覆盖 | 3 | 0 100 0 | 100 | 100 | ACEF | √ |
判定/条件覆盖 | 1 | 10 103 0 | 226 | 226 | ABF | √ |
判定/条件覆盖 | 2 | 10 100 0 | 220 | 220 | ACDF | √ |
判定/条件覆盖 | 3 | 0 100 0 | 100 | 100 | ACEF | √ |
判定/条件覆盖 | 4 | 1 101 1 | 114.7 | 114.7 | ACDF | √ |
判定/条件覆盖 | 5 | 1 1 2 | 10.6 | 10.600000000000001 | ACEF | × |
判定/条件覆盖 | 6 | -1 22--5 | 错误提示 | 错误提示 | ACEF | √ |
组合覆盖 | 1 | 10 102 0 | 224 | 224 | ACF | √ |
组合覆盖 | 2 | 10 100 0 | 220 | 220 | ACDF | √ |
组合覆盖 | 3 | 0 10 0 | 10 | 10 | ACEF | √ |
组合覆盖 | 4 | 1 100 2 | 114.4 | 114.4 | ACDF | √ |
组合覆盖 | 5 | 1 1 1 | 9.8 | 9.8 | ACEF | √ |
组合覆盖 | 6 | -2 -3 -5 | 错误提示 | 错误提示 | ACEF | √ |
3)相应Junit测试脚本、执行结果
package test1; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class Yongjin { Yongjin01 Yongjin01 = new Yongjin01(); @Before public void setUp() throws Exception { } @SuppressWarnings("deprecation") @Test public void testYongjin01() { assertEquals(0.0,Yongjin01.Commission(0, 0, 0),0.0001); //0.0001为结果允许误差 assertEquals(10.0,Yongjin01.Commission(-1,22,-5),0.0001); //-1表示输出数量不满足要求 assertEquals(224.0,Yongjin01.Commission(10, 102, 0),0.0001); assertEquals(10.6,Yongjin01.Commission(1,1,2),0.0001); assertEquals(-9.8,Yongjin01.Commission(-1, -1, -1),0.0001); } }
结果:
4)给出测试参数化和打包测试的脚本,并生成执行结果
测试参数化:
package test1; import static org.junit.Assert.assertEquals; 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; @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, 102, 0, 224.0}, {10, 100, 0, 220.0}, {0, 100, 0, 100.0}, {1, 100, 0, 112.0}, {1, 1, 2, 10.6}, {-1, -1, -1, -9.8}, {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 test1; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({Yongjin.class,ParameterizedTest.class}) public class AllCommission { }
结果:
四、测试小结
(1)测试找到的缺陷清单
1.输入为-1,-1,-1时结果为-9.8,但若是直接运行主函数,则会显示错误信息,显然junit的AssertEquals()存在一定的问题。
(2)对源代码的修改建议 :
1.程序虽然能对负数的输入正确处理,但是显示的值仍为负数,而不会报错。
2.程序需要对小数的出入能够正确处理,而不是数量为小数的时候能够照常计算佣金。
3.Commission函数的函数原型应该是String Commission(int headphone,int shell,int protector),但是自己写的都是为double类型,显然不符。
(3)测试总结与心得体会
这次测试的函数,在画完流程图后发现程序实际上只有一处判断,这个判断有3个分支,即sales>1800,1800>=sales>1000和sales<=1000三种情况,这样只要满足语句覆盖的测试用例就可以满足条件/判定覆盖、组合覆盖以及路径覆盖。而且可以为这3个分支划分3个等价类,再在等价类中各取一个样例做测试用例即可。也就是3个测试用例就可以完成测试。