2017-10-06 7 views
0

J'instrument du code de test pour un projet de recherche. Nous commençons par des cas de test tels queProgramatically Remove try/catch bloque des cas de test

@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); 
} 

Les déclarations assert sont commentées des fichiers .java avec:

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

Ensuite, ils sont instrumentés avec javassist pour se connecter des exceptions (pour être sûr qu'ils se produire dans toutes les séries des cas de test):

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(); 
      } 

     } 
    } 

Ce qui donne:

@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); 
    } 
} 

Mon problème est que le NumberIsTooLargeException est avalé par le bloc try/catch restant dans le code. (Note: la classe Exception peut être n'importe quelle classe, c'est juste un exemple d'un cas problématique.) J'ai donc besoin d'un moyen de me débarrasser de tous les blocs try/catch dans les cas de test avant de les placer dans le mien.

Est-ce que quelqu'un sait comment faire avec javassist ou peut-être une bonne expression régulière que je pourrais exécuter sur le fichier .java avant l'instrumentation pour les supprimer?

Je voudrais terminer par:

@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

En utilisant --no-régression assertions' avec Randoop devrait éliminer la nécessité d'éliminer les assertions. – vinegarbin

+0

Certes, notre script est également capable de gérer des cas de test pré-écrits, auquel cas nous aurions besoin de les commenter manuellement. En outre, il est bon de tester des choses en exécutant les tests d'origine avec des assertions pour s'assurer que l'instrumentation fonctionne comme prévu. – Loren

Répondre

0

J'ai trouvé une solution qui fonctionne. Il ne supprime pas le bloc try/catch, mais il ajoute un jet au début de la capture afin de fournir la fonctionnalité nécessaire.

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

Ce qui fait toute la boucle:

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(); 
      } 
     } 
    }