代码之家  ›  专栏  ›  技术社区  ›  Loren

通过编程从测试用例中删除try/catch块

  •  0
  • Loren  · 技术社区  · 7 年前

    @Test
    public void test025() throws Throwable {
        if (debug)
            System.out.format("%n%s%n", "RegressionTest1.test025");
        java.lang.Double[] d_array2 = new java.lang.Double[] { 1.0d, (-1.0d) };
        org.apache.commons.math.linear.ArrayRealVector arrayRealVector3 = new org.apache.commons.math.linear.ArrayRealVector(d_array2);
        org.apache.commons.math.linear.ArrayRealVector arrayRealVector4 = new org.apache.commons.math.linear.ArrayRealVector(d_array2);
        try {
            org.apache.commons.math.linear.ArrayRealVector arrayRealVector7 = new org.apache.commons.math.linear.ArrayRealVector(d_array2, (int) '4', (int) ' ');
            org.junit.Assert.fail("Expected exception of type org.apache.commons.math.exception.NumberIsTooLargeException");
        } catch (org.apache.commons.math.exception.NumberIsTooLargeException e) {
        }
        org.junit.Assert.assertNotNull(d_array2);
    }
    

    assert语句被注释掉。包含以下内容的java文件:

    original = original.replace("org.junit.Assert.", "//org.junit.Assert.");
    original = original.replace("assert", "//assert");
    

    然后,使用javassist对它们进行检测,以记录任何异常(确保它们在所有测试用例运行中都会发生):

        for (CtMethod testmethod : methods) {
            if (testmethod.getName().startsWith("test")) {
                try {
                    testmethod.insertBefore("semanticrt.statedump.dumpObjectState.setDumpTestCase(\""+testClassName+ "." + testmethod.getName()+"\");");
                    CtClass etype = null;
                    try {
                        etype = pool.get("java.lang.Exception");
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    }
    
                    String exceptionCode = "{ semanticrt.statedump.dumpObjectState.dumpExceptionToFile($e, " +
                            "\"" + outputFileRoot + "."+ testmethod.getName() + ".exception\", false); throw $e; }\n";
                    testmethod.addCatch(exceptionCode, etype);
                } catch (CannotCompileException e) {
                    System.out.println(testmethod);
                    e.printStackTrace();
                }
    
            }
        }
    

    这将产生:

    @Test
    public void test025() throws Throwable {
        try {
            dumpObjectState.setDumpTestCase("RegressionTest1.test025");
            if(debug) {
                System.out.format("%n%s%n", new Object[]{"RegressionTest1.test025"});
            }
    
            Double[] var1 = new Double[]{Double.valueOf(1.0D), Double.valueOf(-1.0D)};
            new ArrayRealVector(var1);
            new ArrayRealVector(var1);
    
            try {
                new ArrayRealVector(var1, 52, 32);
            } catch (NumberIsTooLargeException var6) {
                ;
            }
    
        } catch (Exception var7) {
            dumpObjectState.dumpExceptionToFile(var7, "/home/loren/repos/d4jBugs/Math_45/version/XMLOut//out-RegressionTest1.test025.exception", false);
        }
    }
    

    NumberIsTooLargeException 被代码中剩余的try/catch块吞没。(注意:Exception类可以是任何类,这只是一个有问题的例子。)因此,我需要一种方法,在将它们包装到我的测试用例中之前,消除生成测试用例中的任何try/catch块。

    有人知道如何使用javassist或一个我可以在上运行的好正则表达式来实现这一点吗。java文件在插入之前删除它们?

    最后,我想说:

    @Test
    public void test025() throws Throwable {
        try {
            dumpObjectState.setDumpTestCase("RegressionTest1.test025");
            if(debug) {
                System.out.format("%n%s%n", new Object[]{"RegressionTest1.test025"});
            }
    
            Double[] var1 = new Double[]{Double.valueOf(1.0D), Double.valueOf(-1.0D)};
            new ArrayRealVector(var1);
            new ArrayRealVector(var1);
    
            new ArrayRealVector(var1, 52, 32);
    
        } catch (Exception var7) {
            dumpObjectState.dumpExceptionToFile(var7, "/home/loren/repos/d4jBugs/Math_45/version/XMLOut//out-RegressionTest1.test025.exception", false);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Loren    7 年前

    我找到了一个可行的解决方案。它不会删除try/catch块,但会在catch的开头添加一个throw,以提供所需的功能。

    testmethod.instrument(
        new ExprEditor() {
            public void edit(Handler m)
                    throws CannotCompileException
            {
                m.insertBefore("throw $1;");
            }
        }
    );
    

    这使得整个循环:

        for (CtMethod testmethod : methods) {
            if (testmethod.getName().startsWith("test")) {
                try {
                    testmethod.instrument(
                        new ExprEditor() {
                            public void edit(Handler m)
                                    throws CannotCompileException
                            {
                                m.insertBefore("throw $1;");
                            }
                        }
                    );
                    testmethod.insertBefore("semanticrt.statedump.dumpObjectState.setDumpTestCase(\""+testClassName+ "." + testmethod.getName()+"\");");
                    CtClass etype = null;
                    try {
                        etype = pool.get("java.lang.Exception");
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    }
                    // See addCatch() https://jboss-javassist.github.io/javassist/tutorial/tutorial2.html
                    String exceptionCode = "{ semanticrt.statedump.dumpObjectState.dumpExceptionToFile($e, " +
                            "\"" + outputFileRoot + "."+ testmethod.getName() + ".exception\", false); return; }\n";
                    testmethod.addCatch(exceptionCode, etype);
                } catch (CannotCompileException e) {
                    System.out.println(testmethod);
                    e.printStackTrace();
                }
            }
        }