Java cvprof Coverage Report for
TestSuite.java

    1   package junit.framework;
    2   
    3   import java.util.Vector;
    4   import java.util.Enumeration;
    5   import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.*;
    6   import java.lang.reflect.Constructor;
    7   
    8   /**
    9    * A <code>TestSuite</code> is a <code>Composite</code> of Tests.
   10    * It runs a collection of test cases. Here is an example using
   11    * the dynamic test definition.
   12    * <pre>
   13    * TestSuite suite= new TestSuite();
   14    * suite.addTest(new MathTest("testAdd"));
   15    * suite.addTest(new MathTest("testDivideByZero"));
   16    * </pre>
   17    * Alternatively, a TestSuite can extract the tests to be run automatically.
   18    * To do so you pass the class of your TestCase class to the
   19    * TestSuite constructor.
   20    * <pre>
   21    * TestSuite suite= new TestSuite(MathTest.class);
   22    * </pre>
   23    * This constructor creates a suite with all the methods
   24    * starting with "test" that take no arguments.
   25    *
   26    * @see Test
   27    */
   28   public class TestSuite implements Test {
   29   
   30   	private Vector fTests= new Vector(10);
   31   	private String fName;
   32   
   33       /**
   34   	 * Constructs an empty TestSuite.
   35   	 */
   36   	public TestSuite() {
   37   	}
   38   	
   39   	/**
   40   	 * Constructs a TestSuite from the given class with the given name.
   41   	 * @see TestSuite#TestSuite(Class)
   42   	 */
   43   	public TestSuite(Class theClass, String name) {
   44   		this(theClass);
   45   		setName(name);
   46 > 	}
   47 > 	
   48 > 	/**
   49   	 * Constructs a TestSuite from the given class. Adds all the methods
   50   	 * starting with "test" as test cases to the suite.
   51   	 * Parts of this method was written at 2337 meters in the Hüffihütte,
   52   	 * Kanton Uri
   53   	 */
   54   	 public TestSuite(final Class theClass) {
   55   		fName= theClass.getName();
   56   		try {
   57   			getTestConstructor(theClass); // Avoid generating multiple error messages
   58   		} catch (NoSuchMethodException e) {
   59   			addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
   60   			return;
   61 > 		}
   62 > 
   63   		if (!Modifier.isPublic(theClass.getModifiers())) {
   64   			addTest(warning("Class "+theClass.getName()+" is not public"));
   65   			return;
   66 > 		}
   67 > 
   68   		Class superClass= theClass;
   69   		Vector names= new Vector();
   70   		while (Test.class.isAssignableFrom(superClass)) {
   71   			Method[] methods= superClass.getDeclaredMethods();
   72   			for (int i= 0; i < methods.length; i++) {
   73   				addTestMethod(methods[i], names, theClass);
   74   			}
   75   			superClass= superClass.getSuperclass();
   76   		}
   77   		if (fTests.size() == 0)
   78   			addTest(warning("No tests found in "+theClass.getName()));
   79   	}
   80   	
   81      	/**
   82   	 * Constructs an empty TestSuite.
   83   	 */
   84   	public TestSuite(String name) {
   85   		setName(name);
   86   	}
   87   	
   88   	/**
   89   	 * Adds a test to the suite.
   90   	 */
   91   	public void addTest(Test test) {
   92   		fTests.addElement(test);
   93   	}
   94   
   95   	/**
   96   	 * Adds the tests from the given class to the suite
   97   	 */
   98   	public void addTestSuite(Class testClass) {
   99   		addTest(new TestSuite(testClass));
  100   	}
  101   
  102   	private void addTestMethod(Method m, Vector names, Class theClass) {
  103   		String name= m.getName();
  104   		if (names.contains(name))
  105   			return;
  106   		if (! isPublicTestMethod(m)) {
  107   			if (isTestMethod(m))
  108   				addTest(warning("Test method isn't public: "+m.getName()));
  109   			return;
  110   		}
  111   		names.addElement(name);
  112   		addTest(createTest(theClass, name));
  113   	}
  114   
  115   	/**
  116   	 * ...as the moon sets over the early morning Merlin, Oregon
  117   	 * mountains, our intrepid adventurers type...
  118   	 */
  119   	static public Test createTest(Class theClass, String name) {
  120   		Constructor constructor;
  121   		try {
  122   			constructor= getTestConstructor(theClass);
  123   		} catch (NoSuchMethodException e) {
  124   			return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
  125   		}
  126 > 		Object test;
  127   		try {
  128   			if (constructor.getParameterTypes().length == 0) {
  129   				test= constructor.newInstance(new Object[0]);
  130   				if (test instanceof TestCase)
  131   					((TestCase) test).setName(name);
  132   			} else {
  133   				test= constructor.newInstance(new Object[]{name});
  134   			}
  135   		} catch (InstantiationException e) {
  136   			return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
  137   		} catch (InvocationTargetException e) {
  138 > 			return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
  139   		} catch (IllegalAccessException e) {
  140 > 			return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
  141   		}
  142 > 		return (Test) test;
  143   	}
  144   
  145   	/**
  146   	 * Converts the stack trace into a string
  147   	 */
  148   	private static String exceptionToString(Throwable t) {
  149   		StringWriter stringWriter= new StringWriter();
  150   		PrintWriter writer= new PrintWriter(stringWriter);
  151 > 		t.printStackTrace(writer);
  152 > 		return stringWriter.toString();
  153 > 
  154 > 	}
  155   	
  156   	/**
  157   	 * Counts the number of test cases that will be run by this test.
  158   	 */
  159   	public int countTestCases() {
  160   		int count= 0;
  161   		for (Enumeration e= tests(); e.hasMoreElements(); ) {
  162   			Test test= (Test)e.nextElement();
  163   			count= count + test.countTestCases();
  164   		}
  165   		return count;
  166   	}
  167   	
  168   	/**
  169   	 * Gets a constructor which takes a single String as
  170   	 * its argument or a no arg constructor.
  171   	 */
  172   	public static Constructor getTestConstructor(Class theClass) throws NoSuchMethodException {
  173   		Class[] args= { String.class };
  174   		try {
  175   			return theClass.getConstructor(args);	
  176   		} catch (NoSuchMethodException e) {
  177   			// fall through
  178   		}
  179   		return theClass.getConstructor(new Class[0]);
  180   	}
  181   
  182   	private boolean isPublicTestMethod(Method m) {
  183   		return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
  184   	 }
  185   	 
  186   	private boolean isTestMethod(Method m) {
  187   		String name= m.getName();
  188   		Class[] parameters= m.getParameterTypes();
  189   		Class returnType= m.getReturnType();
  190   		return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
  191   	 }
  192   	 
  193   	/**
  194   	 * Runs the tests and collects their result in a TestResult.
  195   	 */
  196   	public void run(TestResult result) {
  197   		for (Enumeration e= tests(); e.hasMoreElements(); ) {
  198   	  		if (result.shouldStop() )
  199   	  			break;
  200   			Test test= (Test)e.nextElement();
  201 > 			runTest(test, result);
  202   		}
  203   	}
  204   
  205   	public void runTest(Test test, TestResult result) {
  206   		test.run(result);
  207   	}
  208   
  209   	/**
  210   	 * Returns the test at the given index
  211   	 */
  212   	public Test testAt(int index) {
  213   		return (Test)fTests.elementAt(index);
  214   	}
  215 > 	
  216   	/**
  217   	 * Returns the number of tests in this suite
  218   	 */
  219   	public int testCount() {
  220   		return fTests.size();
  221   	}
  222   	
  223   	/**
  224   	 * Returns the tests as an enumeration
  225   	 */
  226   	public Enumeration tests() {
  227   		return fTests.elements();
  228   	}
  229   	
  230   	/**
  231   	 */
  232   	public String toString() {
  233   		if (getName() != null)
  234   			return getName();
  235 > 		return super.toString();
  236 > 	 }
  237 > 	 
  238   	/**
  239   	 * Sets the name of the suite.
  240   	 * @param name The name to set
  241   	 */
  242   	public void setName(String name) {
  243   		fName= name;
  244   	}
  245   
  246   	/**
  247   	 * Returns the name of the suite. Not all
  248   	 * test suites have a name and this method
  249   	 * can return null.
  250   	 */
  251   	public String getName() {
  252   		return fName;
  253   	}
  254 > 
  255   	/**
  256   	 * Returns a test which will fail and log a warning message.
  257   	 */
  258   	private static Test warning(final String message) {
  259   		return new TestCase("warning") {
  260   			protected void runTest() {
  261   				fail(message);
  262   			}
  263   		};
  264 > 	}
  265   }