View Javadoc
1   package eu.simuline.testhelpers;
2   
3   import org.junit.runner.notification.Failure;
4   
5   import org.junit.runner.Description;
6   import org.junit.runner.Result;
7   
8   import java.util.Iterator;
9   import org.junit.AssumptionViolatedException;
10  
11  /**
12   * A simple RunListener which notifies of the events while running tests 
13   * by text output. 
14   *
15   * Created: Wed Jun  7 16:41:14 2006
16   *
17   * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
18   * @version 1.0
19   */
20  public final class TextRunListener extends ExtRunListener {
21  
22      /* -------------------------------------------------------------------- *
23       * constructor.                                                         *
24       * -------------------------------------------------------------------- */
25  
26      /**
27       * Creates a new <code>TextRunListener</code> instance.
28       *
29       */
30      public TextRunListener() {
31  	// is empty. 
32      }
33  
34      /* -------------------------------------------------------------------- *
35       * methods.                                                             *
36       * -------------------------------------------------------------------- */
37  
38      /**
39       * Returns a string representation of <code>desc</code>: 
40       * For atomic tests the display name, 
41       * for suites an xml-style description. 
42       */
43      private static String desc2string(Description desc) {
44  	StringBuffer buf = new StringBuffer();
45  	if (desc.isSuite()) {
46  	    buf.append("<Suite name=\"");
47  	    buf.append(desc.getDisplayName());
48  	    buf.append("\">\n");
49  	    Description child;
50  	    Iterator<Description> iter = desc.getChildren().iterator();
51  	    assert iter.hasNext();
52  	    child = iter.next();
53  	    buf.append(desc2string(child));
54  	    while (iter.hasNext()) {
55  		child = iter.next();
56  		buf.append(", \n");
57  		buf.append(desc2string(child));
58  	    }
59  	    buf.append("\n</Suite>");
60  	} else {
61  	    assert desc.isTest();
62  	    buf.append(desc.getDisplayName());
63  	}
64  	return buf.toString();
65      }
66  
67  
68      /**
69       * Called before any tests 
70       * of a suite described by <code>desc</code> have been run. 
71       * This may be called on an arbitrary thread.
72       *
73       * @param desc
74       *    describes the suite of tests to be run. 
75       */
76      // api-docs inherited from class RunListener
77      public void testRunStarted(Description desc) throws Exception { //NOPMD
78  	System.out.println("T testRunStarted(..." + desc2string(desc));
79      }
80  
81      /**
82       * Called when all tests of the suite 
83       * announced by {@link #testRunStarted(Description)} have finished. 
84       * This may be called on an arbitrary thread. 
85       * <p>
86       * Prints a statistics on the result of the test suite 
87       * to the standard output. 
88       *
89       * @param result 
90       *    the summary of the outcoming of the suite of tests run, 
91       *    including all the tests that failed
92       */
93      // api-docs inherited from class RunListener
94      public void testRunFinished(Result result) throws Exception { //NOPMD
95  	System.out.println("T testRunFinished(..." + result);
96  	System.out.println("Statistics: ");
97  	System.out.println("runs:         " + result.getRunCount());
98  	System.out.println("ignored:      " + result.getIgnoreCount());
99  	System.out.println("failures:     " + result.getFailureCount());
100 	System.out.println("time elapsed: " + result.getRunTime() + "ms");
101 	// **** strange: 
102 	// runs seem without ignores 
103 	// failures seem all runs which did not succeed, 
104 	// i.e. test could not be executed or failed. 
105 	// **** only in singular tests with GUI: 
106 	// ignored seem to be also failures
107     }
108 
109     // api-docs inherited from class RunListener
110     /**
111      * Called when a test suite is about to be started. 
112      * If this method is called for a given {@link Description}, 
113      * then {@link #testSuiteFinished(Description)} 
114      * will also be called for the same {@code Description}. 
115      * <p>
116      * Note that not all runners will call this method, so runners should 
117      * be prepared to handle {@link #testStarted(Description)} calls for tests 
118      * where there was no corresponding {@link #testSuiteStarted(Description)} 
119      * call for the parent {@link Description}.
120      *
121      * @param desc
122      *    the description of the test suite that is about to be run
123      *    (generally a class name)
124      * @since 4.13
125      */
126      public void testSuiteStarted(Description desc) throws Exception { //NOPMD
127 	System.out.println("S testSuiteStarted(...   " + desc);
128     }
129 
130     /**
131      * Called when a test suite has finished, 
132      * whether the test suite succeeds or fails.
133      * This method will not be called for a given {@link Description} 
134      * unless {@link #testSuiteStarted(Description)} was called 
135      * for the same {@link Description}.
136      *
137      * @param desc 
138      *    the description of the test suite that just ran
139      * @since 4.13
140      */
141     public void testSuiteFinished(Description desc) throws Exception { //NOPMD
142 	System.out.println("S testSuiteFinished(...  " + desc);
143     }
144 
145     /**
146      * Called when an atomic test is about to be started. 
147      * An ignored test is never started. 
148      *
149      * @param desc
150      *    the description of the test that is about to be run 
151      *    (generally a class and method name)
152      * @see #testIgnored(Description)
153      */
154     // api-docs inherited from class RunListener
155     public void testStarted(Description desc) throws Exception { //NOPMD
156 	System.out.println("T testStarted(...       " + desc);
157     }
158 
159     /**
160      * Called when an atomic test has finished, 
161      * whether the test succeeds or fails. 
162      * This method must be invoked after a test has been started 
163      * which was indicated by {@link #testStarted(Description)} before. 
164      * An ignored test is never finished. 
165      *
166      * @param desc
167      *    the description of the test that just ran
168      * @see #testIgnored(Description)
169      */
170     // api-docs inherited from class RunListener
171     public void testFinished(Description desc) throws Exception { //NOPMD
172 	System.out.println("T testFinished(         " + desc);
173     }
174 
175     /** 
176      * Called when an atomic test fails to execute properly 
177      * throwing a Throwable, or when a listener throws an exception. 
178      * <p>
179      * In the case of a failure of an atomic test, 
180      * this method is invoked after {@link #testStarted(Description)} 
181      * and before {@link #testFinished(Description)}
182      * with the according description of <code>failure</code> 
183      * from the same thread that called {@link #testStarted(Description)}. 
184      * In case of a failed assumption, instead of this method 
185      * {@link #testAssumptionFailure(Failure)} is invoked 
186      * for the according test. 
187      * <p>
188      * In the case of a listener throwing an exception, 
189      * this method will be called with the description of <code>failure</code> 
190      * given by {@link Description#TEST_MECHANISM}, 
191      * and may be called on an arbitrary thread.
192      *
193      * @param failure 
194      *    describes the test that failed and the exception that was thrown 
195      *    or indicates that a listener has thrown an exception 
196      *    and the according exception. 
197      */
198     // api-docs inherited from class RunListener
199     public void testFailure(Failure failure) throws Exception { //NOPMD
200 	// description and exception 
201 	if (failure.getDescription().equals(Description.TEST_MECHANISM)) {
202 	    System.out.println("FRAMEWORK testFailure(          " + failure);
203 	}
204 
205 	System.out.println("T testFailure(          " + failure);
206     }
207 
208     /**
209      * Called when an atomic test flags 
210      * that it assumes a condition that is false. 
211      * This is treated as ignored with the description of the failure. 
212      * This method is invoked after {@link #testStarted(Description)} 
213      * and before {@link #testFinished(Description)}
214      * with the according description of <code>failure</code>. 
215      * A failed assertion does not count as a failure 
216      * and so {@link #testFailure(Failure)} is not invoked 
217      * for the according test. 
218      * <p>
219      * CAUTION: Although a failed assertion is like an ignored test, 
220      * {@link #testRunFinished(Result)} does not count this as ignored test 
221      * but rather than a passed test. 
222      *
223      * @param failure
224      *    describes the test that failed 
225      *    and the {@link AssumptionViolatedException} that was thrown. 
226      * @see #testIgnored(Description)
227      */
228     public void testAssumptionFailure(Failure failure) {
229 	// description and exception 
230 	assert failure.getException() instanceof AssumptionViolatedException;
231 	System.out.println("T testAssumptionFailure(" + failure);
232     }
233 
234     /**
235      * Called when a test will not be run, 
236      * generally because a test method is annotated 
237      * with {@link org.junit.Ignore}. 
238      * This implies 
239      * that neither {@link #testStarted(Description)} 
240      * nor {@link #testFinished(Description)} are invoked 
241      * for the according test. 
242      * This in turn implies that neither {@link #testFailure(Failure)} 
243      * nor {@link #testAssumptionFailure(Failure)} are invoked. 
244      *
245      * @param desc 
246      *    describes the test that will not be run
247      */
248     // api-docs inherited from class RunListener
249     public void testIgnored(Description desc) throws Exception { //NOPMD
250 	System.out.println("T testIgnored(          " + desc);
251     }
252 
253     // homemade extension 
254     /**
255      * Invoked for stop and for break originated by the user. 
256      */
257     // not clear which test has been aborted. 
258     public void testRunAborted() {
259 	// output text 
260 	System.out.println("S testRunAborted(");
261     }
262 
263     // homemade extension 
264     /**
265      * Invoked if a test class is loaded defining a testsuite 
266      * described by <code>desc</code>. 
267      */
268     public void testClassStructureLoaded(final Description desc) {
269 	System.out.println("S testClassStructureLoaded(" + desc);
270     }
271 }