五、测试-六、优化方案


五、测试

1.单元测试

  单元测试的方式是黑盒测试,即通过每个环节的输入输出情况进行测试。程序由四个类组成,对应生成四个测试类,使用Junit5对其中的主要方法进行测试。测试的大致思路是预先设计较为简单的数独用例,生成新的对象,运行方法,并将阶段性的结果与预先计算的结果相比较。

  有些方法具有返回值,便于设计测试类,例如对 Main::isNumber()进行测试:

//Main::isNumber    public static boolean isNumber(String str){        String reg = "^[0-9]+?$";        return str.matches(reg);        }//MainTest::testIsNumber    @Test    final void testIsNumber() {        Assert.assertEquals(true, Main.isNumber("100"));        Assert.assertEquals(true, Main.isNumber("10a"));        Assert.assertEquals(true, Main.isNumber("4.5"));    }

  对于更多没有返回值的方法,采取验证阶段结果的方法,预测方法执行后对象属性的变化并加以验证。例如对SudokuGenerator::creatFirstBlock()方法的测试,该方法执行后生成数独的第一小宫。测试类中将第一小宫所有值求和验证是否完成。

@Test    final void testCreateFirstBlock() {        SudokuGenerator gen=new SudokuGenerator(1);//只生成一个终局,目的是让测试更容易进行        gen.createFirstBlock();        //阶段执行到被测方法后,不继续执行后续方法,开始验证当前成果        boolean status = true;        int numCrit = 0;        Sudoku su = gen.getSudoku();        for(int i=0;i<3;i++) {            for(int j=0;j<3;j++) {                numCrit+=su.get(i, j);            }        }        //完成的一小宫求和应为45        if(numCrit!=45 || su.get(0, 0)!=2) status = false;        Assert.assertEquals(true, status);            }?

  所有测试类及运行结果:

五、测试-六、优化方案

 五、测试-六、优化方案

 五、测试-六、优化方案

  (其中failure是对被测方法进行了错误输入的验证)

2.系统测试

  本环节主要测试不同输入指令的运行结果。对指令输入的可能情况进行等价类划分后得到测试用例表如下:

五、测试-六、优化方案

  (空白部分表示输入为合法输入,程序正常运行)

3.覆盖率测试

  结合系统测试的用例与单元测试,使用eclipse的插件检测覆盖率。在项目上右键 -> Coverage As -> 2 JUnit Test,就可以在控制台窗口看见覆盖率结果。

五、测试-六、优化方案

4.性能测试

  下载并安装JProfile 11.1试用版, 需要注意的是,当执行插件安装时,需要关闭Eclipse。 在安装向导处选择IDE(eclipse 4.8),点击“Integrate”选择IDE的安装路径。完成后,使用“-clean”参数在命令行窗口打开eclipse,在Window -> Perspective -> Customize Perspective -> Action Set Availability, 找到Profile并选中。之后就可以在main类窗口右键 -> Profile As运行JProfile。需要注意的是,因为项目需要输入参数,所以选择“Profile Configurations...”填写指令在运行。

  在JProfile中,我们主要看的是CPU的占用情况。因此我查看了call tree和hot pot的图表。

五、测试-六、优化方案

五、测试-六、优化方案

  从图表中可以看出与文件写入有关的FileWrite与BufferedWriter明显占用了很大资源,导致整体程序运行较慢。

五、测试-六、优化方案

六、优化方案

  从性能分析中不难看出,由于算法采取单个写入,写入过程给整个程序造成较大拖累,是用时最长的环节。因此下一步优化提速的思路就是将单个写入转换成整体写入,将所有终局数独保存在同一个BufferedWriter中来提升效率。例如,按照一定的格式,开一个较大的int数组。String类由于操作涉及多次new,尽量都替代为StringBuffer的操作来节省空间。此外,本次算法中使用位运算标记数独中数字的使用情况,在判断的逻辑上已经比较简明,今后可以再思考如何从回溯的算法方面继续提高效率。

  由于时间问题没有对程序进行具体的优化,谨记录进一步的想法。

相关推荐