KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > junit > framework > TestSuite


1 package junit.framework;
2
3 import java.io.PrintWriter JavaDoc;
4 import java.io.StringWriter JavaDoc;
5 import java.lang.reflect.Constructor JavaDoc;
6 import java.lang.reflect.InvocationTargetException JavaDoc;
7 import java.lang.reflect.Method JavaDoc;
8 import java.lang.reflect.Modifier JavaDoc;
9 import java.util.ArrayList JavaDoc;
10 import java.util.Enumeration JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.Vector JavaDoc;
13
14 /**
15  * <p>A <code>TestSuite</code> is a <code>Composite</code> of Tests.
16  * It runs a collection of test cases. Here is an example using
17  * the dynamic test definition.
18  * <pre>
19  * TestSuite suite= new TestSuite();
20  * suite.addTest(new MathTest("testAdd"));
21  * suite.addTest(new MathTest("testDivideByZero"));
22  * </pre>
23  * </p>
24  *
25  * <p>Alternatively, a TestSuite can extract the tests to be run automatically.
26  * To do so you pass the class of your TestCase class to the
27  * TestSuite constructor.
28  * <pre>
29  * TestSuite suite= new TestSuite(MathTest.class);
30  * </pre>
31  * </p>
32  *
33  * <p>This constructor creates a suite with all the methods
34  * starting with "test" that take no arguments.</p>
35  *
36  * <p>A final option is to do the same for a large array of test classes.
37  * <pre>
38  * Class[] testClasses = { MathTest.class, AnotherTest.class }
39  * TestSuite suite= new TestSuite(testClasses);
40  * </pre>
41  * </p>
42  *
43  * @see Test
44  */

45 public class TestSuite implements Test {
46
47     /**
48      * ...as the moon sets over the early morning Merlin, Oregon
49      * mountains, our intrepid adventurers type...
50      */

51     static public Test createTest(Class JavaDoc<? extends TestCase> theClass, String JavaDoc name) {
52         Constructor JavaDoc<? extends TestCase> constructor;
53         try {
54             constructor= getTestConstructor(theClass);
55         } catch (NoSuchMethodException JavaDoc e) {
56             return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
57         }
58         Object JavaDoc test;
59         try {
60             if (constructor.getParameterTypes().length == 0) {
61                 test= constructor.newInstance(new Object JavaDoc[0]);
62                 if (test instanceof TestCase)
63                     ((TestCase) test).setName(name);
64             } else {
65                 test= constructor.newInstance(new Object JavaDoc[]{name});
66             }
67         } catch (InstantiationException JavaDoc e) {
68             return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
69         } catch (InvocationTargetException JavaDoc e) {
70             return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
71         } catch (IllegalAccessException JavaDoc e) {
72             return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
73         }
74         return (Test) test;
75     }
76     
77     /**
78      * Gets a constructor which takes a single String as
79      * its argument or a no arg constructor.
80      */

81     public static Constructor JavaDoc<? extends TestCase> getTestConstructor(Class JavaDoc<? extends TestCase> theClass) throws NoSuchMethodException JavaDoc {
82         try {
83             return theClass.getConstructor(String JavaDoc.class);
84         } catch (NoSuchMethodException JavaDoc e) {
85             // fall through
86
}
87         return theClass.getConstructor(new Class JavaDoc[0]);
88     }
89
90     /**
91      * Returns a test which will fail and log a warning message.
92      */

93     public static Test warning(final String JavaDoc message) {
94         return new TestCase("warning") {
95             @Override JavaDoc
96             protected void runTest() {
97                 fail(message);
98             }
99         };
100     }
101
102     /**
103      * Converts the stack trace into a string
104      */

105     private static String JavaDoc exceptionToString(Throwable JavaDoc t) {
106         StringWriter JavaDoc stringWriter= new StringWriter JavaDoc();
107         PrintWriter JavaDoc writer= new PrintWriter JavaDoc(stringWriter);
108         t.printStackTrace(writer);
109         return stringWriter.toString();
110     }
111     
112     private String JavaDoc fName;
113
114     private Vector JavaDoc<Test> fTests= new Vector JavaDoc<Test>(10); // Cannot convert this to List because it is used directly by some test runners
115

116     /**
117      * Constructs an empty TestSuite.
118      */

119     public TestSuite() {
120     }
121     
122     /**
123      * Constructs a TestSuite from the given class. Adds all the methods
124      * starting with "test" as test cases to the suite.
125      * Parts of this method were written at 2337 meters in the Hueffihuette,
126      * Kanton Uri
127      */

128      public TestSuite(final Class JavaDoc<? extends TestCase> theClass) {
129         fName= theClass.getName();
130         try {
131             getTestConstructor(theClass); // Avoid generating multiple error messages
132
} catch (NoSuchMethodException JavaDoc e) {
133             addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
134             return;
135         }
136
137         if (!Modifier.isPublic(theClass.getModifiers())) {
138             addTest(warning("Class "+theClass.getName()+" is not public"));
139             return;
140         }
141
142         Class JavaDoc<?> superClass= theClass;
143         List JavaDoc<String JavaDoc> names= new ArrayList JavaDoc<String JavaDoc>();
144         while (Test.class.isAssignableFrom(superClass)) {
145             for (Method JavaDoc each : superClass.getDeclaredMethods())
146                 addTestMethod(each, names, theClass);
147             superClass= superClass.getSuperclass();
148         }
149         if (fTests.size() == 0)
150             addTest(warning("No tests found in "+theClass.getName()));
151     }
152     
153     /**
154      * Constructs a TestSuite from the given class with the given name.
155      * @see TestSuite#TestSuite(Class)
156      */

157     public TestSuite(Class JavaDoc<? extends TestCase> theClass, String JavaDoc name) {
158         this(theClass);
159         setName(name);
160     }
161     
162     /**
163      * Constructs an empty TestSuite.
164      */

165     public TestSuite(String JavaDoc name) {
166         setName(name);
167     }
168     
169     /**
170      * Constructs a TestSuite from the given array of classes.
171      * @param classes {@link TestCase}s
172      */

173     public TestSuite (Class JavaDoc<?>... classes) {
174         for (Class JavaDoc<?> each : classes)
175             addTest(new TestSuite(each.asSubclass(TestCase.class)));
176     }
177     
178     /**
179      * Constructs a TestSuite from the given array of classes with the given name.
180      * @see TestSuite#TestSuite(Class[])
181      */

182     public TestSuite(Class JavaDoc<? extends TestCase>[] classes, String JavaDoc name) {
183         this(classes);
184         setName(name);
185     }
186     
187     /**
188      * Adds a test to the suite.
189      */

190     public void addTest(Test test) {
191         fTests.add(test);
192     }
193
194     /**
195      * Adds the tests from the given class to the suite
196      */

197     public void addTestSuite(Class JavaDoc<? extends TestCase> testClass) {
198         addTest(new TestSuite(testClass));
199     }
200     
201     /**
202      * Counts the number of test cases that will be run by this test.
203      */

204     public int countTestCases() {
205         int count= 0;
206         for (Test each : fTests)
207             count+= each.countTestCases();
208         return count;
209     }
210
211     /**
212      * Returns the name of the suite. Not all
213      * test suites have a name and this method
214      * can return null.
215      */

216     public String JavaDoc getName() {
217         return fName;
218     }
219      
220     /**
221      * Runs the tests and collects their result in a TestResult.
222      */

223     public void run(TestResult result) {
224         for (Test each : fTests) {
225             if (result.shouldStop() )
226                 break;
227             runTest(each, result);
228         }
229     }
230
231     public void runTest(Test test, TestResult result) {
232         test.run(result);
233     }
234      
235     /**
236      * Sets the name of the suite.
237      * @param name the name to set
238      */

239     public void setName(String JavaDoc name) {
240         fName= name;
241     }
242
243     /**
244      * Returns the test at the given index
245      */

246     public Test testAt(int index) {
247         return fTests.get(index);
248     }
249     
250     /**
251      * Returns the number of tests in this suite
252      */

253     public int testCount() {
254         return fTests.size();
255     }
256     
257     /**
258      * Returns the tests as an enumeration
259      */

260     public Enumeration JavaDoc<Test> tests() {
261         return fTests.elements();
262     }
263     
264     /**
265      */

266     @Override JavaDoc
267     public String JavaDoc toString() {
268         if (getName() != null)
269             return getName();
270         return super.toString();
271      }
272
273     private void addTestMethod(Method JavaDoc m, List JavaDoc<String JavaDoc> names, Class JavaDoc<? extends TestCase> theClass) {
274         String JavaDoc name= m.getName();
275         if (names.contains(name))
276             return;
277         if (! isPublicTestMethod(m)) {
278             if (isTestMethod(m))
279                 addTest(warning("Test method isn't public: "+m.getName()));
280             return;
281         }
282         names.add(name);
283         addTest(createTest(theClass, name));
284     }
285
286     private boolean isPublicTestMethod(Method JavaDoc m) {
287         return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
288      }
289      
290     private boolean isTestMethod(Method JavaDoc m) {
291         return
292             m.getParameterTypes().length == 0 &&
293             m.getName().startsWith("test") &&
294             m.getReturnType().equals(Void.TYPE);
295      }
296 }
Popular Tags