软件测试报告一、问题描述:用Java 实现求两整数的加、减、乘、除运算结果,要求两整数的范围都是[0,100]。
从键盘输入数m,数n,判断他们的范围,若不在[0,100]范围内,则输出提示语,要求重新输入,并且在做除法运算时,当除数为0 时,输出提示语,1.说明除数不能为0将两数的范围定在[0,100],以更好的进行边界值分析,等价类测试等黑盒测 试方法;为充分体现白盒测试的特点,有些地方故意用了 if-else 语句,while 循 环;另外,加、减、乘、除运算分别用了四个函数来计算,这样既可以在主函数 中调用,又可以在Junit 框架中分别对这四种运算进行测试。
】、程序源代码:import java.util.Sca nner;2. public class Computer {3. privat e int a;4. privat e int b;5. publi cComputer ( int x,int y) // 构造函数,初始化6. 7. a=x;II 注意:Juint 中需要输入测试值在0~100范围内8. 9. 10. publicdouble add() 〃加法11. 12. return a+ b;14. public double minu s()II 减法return a-b;}public double multiply() // 乘法{return a*b;}public double divide() // 除法,要求除数不能为 0 ,否则输出提示语{if (b !=0)return a/b;elseSystem. out .println( "除数不能为 0! ");return 0;}public static void main(String[] args){Scanner scanner = null ;scanner = new Scanner(System. in );System. out .println( " 请输入 0~100 的两个 m,n 整数 :");System. out .println( "请输入第一个数: ");while (true ){ // 若输入值不在要求范围内,则有循环直到输入正确为止int m = scanner.nextInt();16. 17. 18. 19. 20.21. 22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.if (m>=0&&m<=100) {System. out .println( "请输入第二个数: "); while (true ){ int n = scanner.nextInt();if (n>=0&&n<=100) Computer cpt= new Computer(m,n); System.out .println( "运算结果是: ");System.out .println( " 加法 :"+m+ "+" +n+ "=" +cpt.add()); System.out .println( " 减法 :"+m+ "-" +n+ "=" +cpt.minus());System.out .println( " 乘法 :"+m+ "*" +n+ "=" +cpt.multiply(); System.out .println(" 除法 :"+m+ "/" +n+ "=" +cpt.divide());}else System. out .print("输入n 值不在要求区间,请重新输入n : \n");}}elseSystem. out .print ("输入m 值不在要求区间,请重新输入m : \n");38. 39. 40. 41. 42.43. 44.45. 46. 47. 48. 49. 50.51.52. 53.54. 55. 56. 57. 58. 59.60. }三、黑盒测试:1、边界值测试:1.1、边界值分析:输入要求是0~100之间的整数,因此产生了0和100两个边界,边界值分析可产生4*2+1=9 个测试用例。
可构造(50,0)、(50,1)、(50,50)、(50,99)、(50, 100)、(0,50)、(1,50)、(99,50)、(100,50)这9 组测试用例。
表1边界值分析测试用例在该测试时,发现(50,0)这个测试的除法的预期输出和实际输出不一致, 是因为代码中return 0;当除数n=0时,实际返回的是0.0。
public double divide(){if (b !=0)retur n a/b;elseSystem. out .println(”除数不能为 0!");return 0; // 出现 Bug}1.2健壮性测试:健壮性测试可产生6*2+1=13 个测试用例,在上面边界值分析测试用例的基础上再添加(50,-1)、(50,101)、(-1,50)、(101,50)这4个测试用例即可。
表2健壮性测试用例2、等价类测试:规定了输入值m , n的范围[0 ,100],贝U变量的有效等价类:M 仁{m : 0 <m <100}N仁{n:0 <n <100}变量的无效等价类:M2={m:m <0}M3={m:m >100}N2={n:n <0}N3={n:n >0}2.1、弱一般等价类测试:该测试可用每个等价类的一个变量实现,可生成1个测试用例。
2.2、强一般等价类测试:该测试基于多缺陷假设,需要1*1=1个测试用例。
表3 强、弱一般等价类测试用例2.3、弱健壮等价类测试:该测试基于单缺陷假设,不仅对有效值测试,还考虑了无效值,可生成1+2+2=5 个测试用例。
表4 弱健壮等价类测试用例2.4、强健壮等价类测试:该测试基于多缺陷假设,从所有等价类笛卡尔积的每个元素中获得测试用例,可生成(1+2)*(1+2)=9个测试用例。
表5 弱健壮等价类测试用例el :输出结果e2 :输入m 值不在区间e3 :输入n 值不在区间mCe2Ce33、因果图:C1 :输入 m 值在[0,100]内C2 :输入n 值在[0,100]内3.基于决策表的测试:变量的有效等价类:M 仁{m : 0 <m <100}N仁{n:0 <n <100}变量的无效等价类:M2={m:m <0}M3={m:m >100}N2={n:n <0}N3={n:n >0}表6 基于决策表的测试用例-白盒测试: 1.测试覆盖指标:流程图:1.1、语句覆盖:每个可执行的语句必须至少执行一次,则测试用例:表7 语句覆盖测试用例1.2、(判定)分支覆盖:每个判定必须至少获得一次“真”值和“假”值,贝U测试用例:表8 (判定)分支覆盖1.3、条件判定覆盖:每个判定中的每个条件的所有可能值(真/假)至少出现一次并且每个判定本身的结果(真/假)也至少出现一次,则测试用例:表9条件判定覆盖1.4、路径覆盖:测试用例要求覆盖所有可能的路径:表10 路径覆盖2.基路径测(为简便画图,开始点从主要代码第36行开始, 其他无分支节点用省略号表示)(从节点43到51)所以:圈复杂度V(G)= 54 个独立路径为:P1:1,...,36,37,38...42,43...54,55,58,59,60P2:1,...,36,37,56,57,58,59,60P3:1,...,36,37,38...42,52,53,54,55,58,59,60P4:1,...,36,37,38...42,43...54,42,52,53,54,55,58,59,60P5:1,...,36,37,56,57,58,36,37,56,57,58,59,60三、Junit 动态测试:import junit.framework.TestCase; // 引入 Junit 框架中所有类public class ComputerT est extends TestCase {private Computer a; // 定义变量private Computer b;private Computer c;private Computer d;public ComputerTest (String name) {super (n ame); //构造函数,使用super关键字直接引用父类TestCase的构造函数}protected void setUp() throws Exception {super .setUp(); // 建立环境,可以进行一些测试数据的初始化,还可以把数据库联接写在此处,以减少重复性工作,提高效率a = new Computer(1,99);b = new Computer(101,5);c = new Computer(1,2);d = new Computer(1,0); }protected void tearDown() throws super .tearDown();}public void testComputer() {int x=1;int y=1;assertSame (x,y);}public void testAdd() {assertEquals (100.0, a.add()); }public void testAdd1() {assertEquals (106.0, b.add()); Exception{//assertSame()// 加法测试// 输入值超出要求范围,测试失败,因为要求0~100范围,所以,在构造Computer。
函数时,要规定变量x, y的范围}public void testMinus() { // 减法测试assertEquals (-89, a.minus()); // 预期值和结果不相等,测试失败public void testMinus1() {assertEquals (-89.0, a.minus());}public void testMultiply() {assertEquals (2.0, c.multiply());}public void testMultiply1() {Object tx = null ;try {assertEquals (2.0, c.multiply()); 〃c.multiply() 的正常结果是2.0 ,所以在此不应抛出异常fail ("should have thrown an exception "); // 上面不抛出异常,不执行fail()}catch (Exception e) {tx = e;}assertNotNull (tx); //断言tx不为空,则一定有异常}public void testDivide() {assertEquals (0.0,d .divide()); // 因divide()函数中,当d=0 时,返回0.0,所以这里测试应该成功,虽然希望得到“被除数不能为0!”的情况public void testDivide1() {assertEquals (0.5, c.divide());}public void testEmpty(){try {c.divide();fail ("should have thrown an exception " );}catch (RuntimeException Ex){assertTrue (true ); //assertTrue(true);}}}截图:⑴、测试testAdd1()时,由于b=newComputer(101,5); assertEquals (106.0, b.add());输入值范围超出定义范围,测试异常;⑵、测试testMinus()时,assertEquals (-89, a.minus());预期值和实际值不相同, 测试异常;⑶、测试testMultiply()时,断言不为空,抛出异常Junit集成测试:在Junit中,Test Case总是对所有方法进行测试,而Test Suite中可对其中的一部分方法测试,而且一个测试类中还可以包含其他测试类。