Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.jorphan.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.List; import java.util.Locale; import java.util.Properties; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.textui.TestRunner; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.logging.LoggingManager; import org.apache.jorphan.reflect.ClassFinder; import org.apache.jorphan.util.JOrphanUtils; import org.apache.log.Logger; /** * Provides a quick and easy way to run all <a * href="http://junit.sourceforge.net">junit</a> unit tests in your java * project. It will find all unit test classes and run all their test methods. * There is no need to configure it in any way to find these classes except to * give it a path to search. * <p> * Here is an example Ant target (See Ant at <a * href="http://jakarta.apache.org/ant">Apache</a>) that runs all your unit * tests: * * <pre> * * <target name="test" depends="compile"> * <java classname="org.apache.jorphan.test.AllTests" fork="yes"> * <classpath> * <path refid="YOUR_CLASSPATH"/> * <pathelement location="ROOT_DIR_OF_YOUR_COMPILED_CLASSES"/> * </classpath> * <arg value="SEARCH_PATH/"/> * <arg value="PROPERTY_FILE"/> * <arg value="NAME_OF_UNITTESTMANAGER_CLASS"/> * </java> * </target> * * </pre> * * <dl> * <dt>YOUR_CLASSPATH</dt> * <dd>Refers to the classpath that includes all jars and libraries need to run * your unit tests</dd> * * <dt>ROOT_DIR_OF_YOUR_COMPILED_CLASSES</dt> * <dd>The classpath should include the directory where all your project's * classes are compiled to, if it doesn't already.</dd> * * <dt>SEARCH_PATH</dt> * <dd>The first argument tells AllTests where to look for unit test classes to * execute. In most cases, it is identical to ROOT_DIR_OF_YOUR_COMPILED_CLASSES. * You can specify multiple directories or jars to search by providing a * comma-delimited list.</dd> * * <dt>PROPERTY_FILE</dt> * <dd>A simple property file that sets logging parameters. It is optional and * is only relevant if you use the same logging packages that JOrphan uses.</dd> * * <dt>NAME_OF_UNITTESTMANAGER_CLASS</dt> * <dd>If your system requires some configuration to run correctly, you can * implement the {@link UnitTestManager} interface and be given an opportunity * to initialize your system from a configuration file.</dd> * </dl> * * @see UnitTestManager */ public final class AllTests { private static final Logger log = LoggingManager.getLoggerForClass(); /** * Private constructor to prevent instantiation. */ private AllTests() { } private static void logprop(String prop, boolean show) { String value = System.getProperty(prop); log.info(prop + "=" + value); if (show) { System.out.println(prop + "=" + value); } } private static void logprop(String prop) { logprop(prop, false); } /** * Starts a run through all unit tests found in the specified classpaths. * The first argument should be a list of paths to search. The second * argument is optional and specifies a properties file used to initialize * logging. The third argument is also optional, and specifies a class that * implements the UnitTestManager interface. This provides a means of * initializing your application with a configuration file prior to the * start of any unit tests. * * @param args * the command line arguments */ public static void main(String[] args) { if (args.length < 1) { System.out.println("You must specify a comma-delimited list of paths to search " + "for unit tests"); return; } String home = new File(System.getProperty("user.dir")).getParent(); System.out.println("Setting JMeterHome: " + home); JMeterUtils.setJMeterHome(home); initializeLogging(args); initializeManager(args); String version = "JMeterVersion=" + JMeterUtils.getJMeterVersion(); log.info(version); System.out.println(version); logprop("java.version", true); logprop("java.vm.name"); logprop("java.vendor"); logprop("java.home", true); logprop("file.encoding", true); // Display actual encoding used (will differ if file.encoding is not recognised) String msg = "default encoding=" + Charset.defaultCharset(); System.out.println(msg); log.info(msg); logprop("user.home"); logprop("user.dir", true); logprop("user.language"); logprop("user.region"); logprop("user.country"); logprop("user.variant"); final String showLocale = "Locale=" + Locale.getDefault().toString(); log.info(showLocale); System.out.println(showLocale); logprop("os.name", true); logprop("os.version", true); logprop("os.arch"); logprop("java.class.version"); // logprop("java.class.path"); String cp = System.getProperty("java.class.path"); String cpe[] = JOrphanUtils.split(cp, java.io.File.pathSeparator); StringBuilder sb = new StringBuilder(3000); sb.append("java.class.path="); for (int i = 0; i < cpe.length; i++) { sb.append("\n"); sb.append(cpe[i]); if (new java.io.File(cpe[i]).exists()) { sb.append(" - OK"); } else { sb.append(" - ??"); } } log.info(sb.toString()); // ++ // GUI tests throw the error // testArgumentCreation(org.apache.jmeter.config.gui.ArgumentsPanel$Test)java.lang.NoClassDefFoundError // at java.lang.Class.forName0(Native Method) // at java.lang.Class.forName(Class.java:141) // at // java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62) // // Try to find out why this is ... System.out.println("+++++++++++"); logprop("java.awt.headless", true); logprop("java.awt.graphicsenv", true); // // try {// // Class c = Class.forName(n); // System.out.println("Found class: "+n); // // c.newInstance(); // // System.out.println("Instantiated: "+n); // } catch (Exception e1) { // System.out.println("Error finding class "+n+" "+e1); // } catch (java.lang.InternalError e1){ // System.out.println("Error finding class "+n+" "+e1); // } // System.out.println("------------"); // don't call isHeadless() here, as it has a side effect. // -- System.out.println("Creating test suite"); TestSuite suite = suite(args[0]); int countTestCases = suite.countTestCases(); System.out.println("Starting test run, test count = " + countTestCases); // for (int i=0;i<suite.testCount();i++){ // Test testAt = suite.testAt(i); // int testCases = testAt.countTestCases(); // if (testAt instanceof junit.framework.TestCase){ // System.out.print(((junit.framework.TestCase) testAt).getName()); // } // if (testAt instanceof TestSuite){ // TestSuite testSuite = ((TestSuite) testAt); // String name = testSuite.getName(); // System.out.print(name); // System.out.println(" "+testCases); // } // } // Jeremy Arnold: This method used to attempt to write results to // a file, but it had a bug and instead just wrote to System.out. // Since nobody has complained about this behavior, I'm changing // the code to not attempt to write to a file, so it will continue // behaving as it did before. It would be simple to make it write // to a file instead if that is the desired behavior. TestResult result = TestRunner.run(suite); // ++ // Recheck settings: //System.out.println("+++++++++++"); // System.out.println(e+"="+System.getProperty(e)); // System.out.println(g+"="+System.getProperty(g)); // System.out.println("Headless? // "+java.awt.GraphicsEnvironment.isHeadless()); // try { // Class c = Class.forName(n); // System.out.println("Found class: "+n); // c.newInstance(); // System.out.println("Instantiated: "+n); // } catch (Exception e1) { // System.out.println("Error with class "+n+" "+e1); // } catch (java.lang.InternalError e1){ // System.out.println("Error with class "+n+" "+e1); // } //System.out.println("------------"); // -- System.exit(result.wasSuccessful() ? 0 : 1); // this is needed because the test may start the AWT EventQueue thread which is not a daemon. } /** * An overridable method that initializes the logging for the unit test run, * using the properties file passed in as the second argument. * * @param args */ protected static void initializeLogging(String[] args) { if (args.length >= 2) { Properties props = new Properties(); InputStream inputStream = null; try { System.out.println("Setting up logging props using file: " + args[1]); inputStream = new FileInputStream(args[1]); props.load(inputStream); LoggingManager.initializeLogging(props); } catch (FileNotFoundException e) { System.out.println(e.getLocalizedMessage()); } catch (IOException e) { System.out.println(e.getLocalizedMessage()); } finally { JOrphanUtils.closeQuietly(inputStream); } } } /** * An overridable method that that instantiates a UnitTestManager (if one * was specified in the command-line arguments), and hands it the name of * the properties file to use to configure the system. * * @param args */ protected static void initializeManager(String[] args) { if (args.length >= 3) { try { System.out.println("Using initializeProperties() from " + args[2]); UnitTestManager um = (UnitTestManager) Class.forName(args[2]).newInstance(); System.out.println("Setting up initial properties using: " + args[1]); um.initializeProperties(args[1]); } catch (ClassNotFoundException e) { System.out.println("Couldn't create: " + args[2]); e.printStackTrace(); } catch (InstantiationException e) { System.out.println("Couldn't create: " + args[2]); e.printStackTrace(); } catch (IllegalAccessException e) { System.out.println("Couldn't create: " + args[2]); e.printStackTrace(); } } } /* * Externally callable suite() method for use by JUnit Allows tests to be * run directly under JUnit, rather than using the startup code in the rest * of the module. No parameters can be passed in, so it is less flexible. */ public static TestSuite suite() { String args[] = { "../lib/ext", "./jmetertest.properties", "org.apache.jmeter.util.JMeterUtils" }; initializeManager(args); return suite(args[0]); } /** * A unit test suite for JUnit. * * @return The test suite */ private static TestSuite suite(String searchPaths) { TestSuite suite = new TestSuite("All Tests"); System.out.println("Scanning " + searchPaths + " for test cases"); int tests = 0; int suites = 0; try { log.info("ClassFinder(TestCase)"); List<String> classList = ClassFinder.findClassesThatExtend(JOrphanUtils.split(searchPaths, ","), new Class[] { TestCase.class }, true); int sz = classList.size(); log.info("ClassFinder(TestCase) found: " + sz + " TestCase classes"); System.out.println("ClassFinder found: " + sz + " TestCase classes"); for (String name : classList) { try { /* * TestSuite only finds testXXX() methods, and does not look * for suite() methods. * * To provide more compatibilty with stand-alone tests, * where JUnit does look for a suite() method, check for it * first here. * */ Class<?> clazz = Class.forName(name); Test t = null; try { Method m = clazz.getMethod("suite", new Class[0]); t = (Test) m.invoke(clazz, (Object[]) null); suites++; } catch (NoSuchMethodException e) { } // this is not an error, the others are // catch (SecurityException e) {} // catch (IllegalAccessException e) {} // catch (IllegalArgumentException e) {} // catch (InvocationTargetException e) {} if (t == null) { t = new TestSuite(clazz); } tests++; suite.addTest(t); } catch (Exception ex) { System.out.println("ERROR: (see logfile) could not add test for class " + name + " " + ExceptionUtils.getStackTrace(ex)); log.error("error adding test :", ex); } } } catch (IOException e) { log.error("", e); } System.out.println("Created: " + tests + " tests including " + suites + " suites"); return suite; } }