use of fr.inria.diversify.compare.Observation in project dspot by STAMP-project.
the class MethodsAssertGenerator method generateAsserts.
/**
* Generates assertions and try/catch/fail blocks for multiple tests.
*
* <p>Assertion Amplification process.
* <ol>
* <li>Instrumentation to collect the state of the program after execution (but before assertions).</li>
* <li>Collection of actual values by running the tests.</li>
* <li>Generation of new assertions in place of observation points.
* Generation of catch blocks if a test raises an exception.</li>
* </ol>
* The details of the first two points are in {@link #addAssertions(CtType, List)}.
*
* @param testClass Test class
* @param tests Test methods
* @return New tests with new assertions
* @throws IOException
* @throws ClassNotFoundException
*/
public List<CtMethod<?>> generateAsserts(CtType testClass, List<CtMethod<?>> tests) throws IOException, ClassNotFoundException {
LOGGER.info("Run tests. ({})", tests.size());
final TestListener result = TestCompiler.compileAndRun(testClass, this.compiler, tests, this.configuration);
if (result == null) {
return Collections.emptyList();
} else {
final List<String> failuresMethodName = result.getFailingTests().stream().map(Failure::getDescription).map(Description::getMethodName).collect(Collectors.toList());
final List<String> passingMethodName = result.getPassingTests().stream().map(Description::getMethodName).collect(Collectors.toList());
final List<CtMethod<?>> generatedTestWithAssertion = new ArrayList<>();
// add assertion on passing tests
if (!passingMethodName.isEmpty()) {
LOGGER.info("{} test pass, generating assertion...", passingMethodName.size());
List<CtMethod<?>> passingTests = addAssertions(testClass, tests.stream().filter(ctMethod -> passingMethodName.contains(ctMethod.getSimpleName())).collect(Collectors.toList())).stream().filter(Objects::nonNull).collect(Collectors.toList());
if (passingTests != null) {
generatedTestWithAssertion.addAll(passingTests);
}
}
// add try/catch/fail on failing/error tests
if (!failuresMethodName.isEmpty()) {
LOGGER.info("{} test fail, generating try/catch/fail blocks...", failuresMethodName.size());
final List<CtMethod<?>> failingTests = tests.stream().filter(ctMethod -> failuresMethodName.contains(ctMethod.getSimpleName())).map(ctMethod -> makeFailureTest(ctMethod, result.getFailureOf(ctMethod.getSimpleName()))).filter(Objects::nonNull).collect(Collectors.toList());
if (!failingTests.isEmpty()) {
generatedTestWithAssertion.addAll(failingTests);
}
}
return generatedTestWithAssertion;
}
}
use of fr.inria.diversify.compare.Observation in project dspot by STAMP-project.
the class MethodsAssertGenerator method addAssertions.
/**
* Adds new assertions in multiple tests.
*
* <p>Instruments the tests to have observation points.
* Details in {@link AssertGeneratorHelper#createTestWithLog(CtMethod, String)}.
*
* <p>Details of the assertion generation in {@link #buildTestWithAssert(CtMethod, Map)}.
*
* @param testClass Test class
* @param testCases Passing test methods
* @return New tests with new assertions generated from observation points values
* @throws IOException
* @throws ClassNotFoundException
*/
private List<CtMethod<?>> addAssertions(CtType<?> testClass, List<CtMethod<?>> testCases) throws IOException, ClassNotFoundException {
CtType clone = testClass.clone();
testClass.getPackage().addType(clone);
LOGGER.info("Add observations points in passing tests.");
LOGGER.info("Instrumentation...");
final List<CtMethod<?>> testCasesWithLogs = testCases.stream().map(ctMethod -> {
DSpotUtils.printProgress(testCases.indexOf(ctMethod), testCases.size());
return AssertGeneratorHelper.createTestWithLog(ctMethod, this.originalClass.getPackage().getQualifiedName());
}).collect(Collectors.toList());
final List<CtMethod<?>> testsToRun = new ArrayList<>();
IntStream.range(0, 3).forEach(i -> testsToRun.addAll(testCasesWithLogs.stream().map(CtMethod::clone).map(ctMethod -> {
ctMethod.setSimpleName(ctMethod.getSimpleName() + i);
return ctMethod;
}).map(ctMethod -> {
clone.addMethod(ctMethod);
return ctMethod;
}).collect(Collectors.toList())));
ObjectLog.reset();
LOGGER.info("Run instrumented tests. ({})", testsToRun.size());
final TestListener result = TestCompiler.compileAndRun(clone, this.compiler, testsToRun, this.configuration);
if (result == null || !result.getFailingTests().isEmpty()) {
return Collections.emptyList();
} else {
Map<String, Observation> observations = ObjectLog.getObservations();
LOGGER.info("Generating assertions...");
return testCases.stream().map(ctMethod -> this.buildTestWithAssert(ctMethod, observations)).collect(Collectors.toList());
}
}
Aggregations