Java tutorial
/* * Copyright (C) 2014 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package interactivespaces.workbench.project.test; import org.apache.commons.logging.Log; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import java.io.File; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; /** * Run all Java unit tests for a project. * * <p> * This class is meant to be run inside its own classloader. * * @author Keith M. Hughes */ public class IsolatedJavaTestRunner { /** * Run the given tests in the given classLoader. * * @param testCompilationFolder * the folder for * @param classLoader * class loader to use for running tests * @param log * logger for the test run * * @return {@code true} if all tests passed */ public boolean runTests(File testCompilationFolder, URLClassLoader classLoader, Log log) { // Get all JUnit tests JunitTestClassDetector detector = new JunitTestClassDetector(); List<JunitTestClassVisitor> testClasses = detector.findTestClasses(testCompilationFolder); List<String> testClassNames = new ArrayList<String>(); if (!testClasses.isEmpty()) { for (JunitTestClassVisitor testClass : testClasses) { testClassNames.add(testClass.getClassName().replaceAll("\\/", ".")); } return runJunitTests(classLoader, testClassNames, log); } else { log.warn(String.format("No JUnit test classes found in %s", testCompilationFolder.getAbsolutePath())); // No tests. Claim they successfully ran anyway. return true; } } /** * Run all JUnit tests. * * @param classLoader * the classloader for loading test classes * @param testClassNames * the names of the detected JUnit classes * @param log * logger for the test run * * @return {@code true} if all tests succeeded */ private boolean runJunitTests(URLClassLoader classLoader, List<String> testClassNames, final Log log) { JUnitCore junit = new JUnitCore(); junit.addListener(new RunListener() { @Override public void testFailure(Failure failure) throws Exception { reportFailure(failure, log); } @Override public void testAssumptionFailure(Failure failure) { reportFailure(failure, log); } }); log.info("Starting JUnit tests"); boolean allSucceeded = true; for (String testClassName : testClassNames) { try { Class<?> testClass = classLoader.loadClass(testClassName); Result result = junit.run(testClass); log.info(String.format("Ran %2d tests in %4dms: %d failed, %d ignored. (%s)", result.getRunCount(), result.getRunTime(), result.getFailureCount(), result.getIgnoreCount(), testClassName)); allSucceeded &= result.wasSuccessful(); } catch (Exception e) { log.error(String.format("Error while running test class %s", testClassName), e); } } log.info("JUnit tests complete"); return allSucceeded; } /** * Report a test failure. * * @param testFailure * the test failure * @param log * logger for the test run */ private void reportFailure(Failure testFailure, Log log) { log.error(String.format("Test %s failed\n%s\n", testFailure.getTestHeader(), trimStackTrace(testFailure))); } /** * Trim stack trace to stop before everything about the fact that Java * reflection called the test method. * * @param failure * the JUnit failure * * @return the trimmed stack trace */ private String trimStackTrace(Failure failure) { String trace = failure.getTrace(); String testclass = failure.getDescription().getClassName(); int lastIndexOf = trace.lastIndexOf(testclass); int endOfLine = trace.indexOf("\n", lastIndexOf); return trace.substring(0, endOfLine); } }