/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package org.evosuite.eclipse.replace; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.evosuite.Properties; import org.evosuite.Properties.Algorithm; import org.evosuite.Properties.Strategy; import org.evosuite.TestSuiteGenerator; import org.evosuite.coverage.TestFitnessFactory; import org.evosuite.ga.metaheuristics.GeneticAlgorithm; import org.evosuite.strategy.PropertiesSuiteGAFactory; import org.evosuite.strategy.PropertiesTestGAFactory; // import org.evosuite.junit.JUnitTestReader; import org.evosuite.testcase.TestCase; import org.evosuite.testcase.TestCaseMinimizer; import org.evosuite.testcase.TestChromosome; import org.evosuite.testcase.TestFitnessFunction; import org.evosuite.testcase.execution.ExecutionTracer; import org.evosuite.testcase.factories.RandomLengthTestFactory; import org.evosuite.testsuite.TestSuiteChromosome; /** * This class is the main entry point for test case replacement * */ public class TestCaseReplacer { /** * Given a test, create a GA and look for a replacement test * * @param test */ public TestCase replaceTest(String targetClass, List<TestCase> otherTests, TestCase test) { // Various environmental setup necessary for EvoSuite Properties.ALGORITHM = Algorithm.MONOTONICGA; Properties.STRATEGY = Strategy.ONEBRANCH; ExecutionTracer.enableTraceCalls(); // Run for 10 generations - adapt as necessary // Properties.STOPPING_CONDITION = StoppingCondition.MAXGENERATIONS; // Properties.SEARCH_BUDGET = 20; // Properties.STOPPING_CONDITION = StoppingCondition.MAXTIME; // Properties.SEARCH_BUDGET = 20; // GeneticAlgorithm ga = TestSuiteGenerator.getGeneticAlgorithm(new RandomLengthTestFactory()); // TODO: JM: Needs Testing. Not sure if this is equivalent: PropertiesTestGAFactory algorithmFactory = new PropertiesTestGAFactory(); GeneticAlgorithm<TestChromosome> ga = algorithmFactory.getSearchAlgorithm(); List<TestFitnessFactory<? extends TestFitnessFunction>> factories = TestSuiteGenerator.getFitnessFactories(); Collection<TestFitnessFunction> fitnessFunctions = new ArrayList<TestFitnessFunction>(); for (TestFitnessFactory<? extends TestFitnessFunction> factory : factories) { // Set up fitness function for the parsed test case DifferenceFitnessFunction fitnessFunction = new DifferenceFitnessFunction(test, otherTests, factory); //ga.setFitnessFunction(fitness); fitnessFunctions.add(fitnessFunction); ga.addFitnessFunction(fitnessFunction); } // Perform calculation ga.generateSolution(); // The best individual at the end of the search contains our candidate solution TestChromosome testChromosome = (TestChromosome) ga.getBestIndividual(); TestCaseMinimizer minimizer = new TestCaseMinimizer(fitnessFunctions); minimizer.minimize(testChromosome); System.out.println("Best individual has fitness: " + testChromosome.getFitness()); return testChromosome.getTestCase(); } /** * Try to parse test case from a file, then start replacement * * @param fileName * Name of the file containing the unit tests * * @param testName * Method name of the test= */ public TestCase replaceTest(String targetClass, String fileName, String testName, String[] classPath) { Map<String, TestCase> tests = getTestCases(fileName, classPath); TestCase target = tests.get(testName); System.out.println("Found target test: " + target.toCode()); tests.remove(testName); //remove "test5" method name return replaceTest(targetClass, new ArrayList<TestCase>(tests.values()), target); } /** * Parse all the tests in the given file * * @param fileName * @return */ private Map<String, TestCase> getTestCases(String fileName, String[] classPath) { // JUnitTestReader parser = new JUnitTestReader(classPath, new String[0]); Map<String, TestCase> tests = new HashMap<String, TestCase>(); // TODO: // tests.putAll(parser.readTests(fileName)); if (tests.isEmpty()) { System.err.println("Found no parsable test cases in file " + fileName); System.exit(1); } return tests; } /** * Main method when class is invoked. Parses a file, selects a test, and * calculates a replacement. The replacement is simply output to the console * * @param args * arguments: filename and number of test */ public static void main(String[] args) { if (args.length != 3) { System.err.println("Usage: TestCaseReplacer <targetClass> <filename> <methodname>"); System.exit(1); } Properties.TARGET_CLASS = args[0]; TestCaseReplacer replacer = new TestCaseReplacer(); TestCase result = replacer.replaceTest(args[0], args[1], args[2], System.getProperty("java.class.path").split(":")); System.out.println("Resulting test case:"); System.out.println(result.toCode()); System.exit(0); } }