Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: junit/framework/TestSuite.java


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