1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.woopi.ant.taskdefs.junit;
19 import java.io.BufferedWriter;
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.io.OutputStreamWriter;
23 import java.io.Writer;
24 import java.util.Enumeration;
25 import java.util.Hashtable;
26 import java.util.Properties;
27 import javax.xml.parsers.DocumentBuilder;
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import junit.framework.AssertionFailedError;
30 import junit.framework.Test;
31 import org.apache.tools.ant.BuildException;
32 import org.apache.tools.ant.util.DOMElementWriter;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.Text;
36
37
38 /***
39 * Prints XML output of the test to a specified Writer.
40 *
41 *
42 * @see FormatterElement
43 */
44
45 public class JavadocXMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants {
46
47 private static DocumentBuilder getDocumentBuilder() {
48 try {
49 return DocumentBuilderFactory.newInstance().newDocumentBuilder();
50 } catch (Exception exc) {
51 throw new ExceptionInInitializerError(exc);
52 }
53 }
54
55 /***
56 * The XML document.
57 */
58 private Document doc;
59 /***
60 * The wrapper for the whole testsuite.
61 */
62 private Element rootElement;
63 /***
64 * Element for the current test.
65 */
66 private Hashtable testElements = new Hashtable();
67 /***
68 * tests that failed.
69 */
70 private Hashtable failedTests = new Hashtable();
71 /***
72 * Timing helper.
73 */
74 private Hashtable testStarts = new Hashtable();
75 /***
76 * Where to write the log to.
77 */
78 private OutputStream out;
79
80 public JavadocXMLJUnitResultFormatter() {
81 }
82
83 public void setOutput(OutputStream out) {
84 this.out = out;
85 }
86
87 public void setSystemOutput(String out) {
88 formatOutput(SYSTEM_OUT, out);
89 }
90
91 public void setSystemError(String out) {
92 formatOutput(SYSTEM_ERR, out);
93 }
94
95 /***
96 * The whole testsuite started.
97 */
98 public void startTestSuite(JUnitTest suite) {
99 doc = getDocumentBuilder().newDocument();
100 rootElement = doc.createElement(TESTSUITE);
101 rootElement.setAttribute(ATTR_NAME, suite.getName());
102
103
104 Element propsElement = doc.createElement(PROPERTIES);
105 rootElement.appendChild(propsElement);
106 Properties props = suite.getProperties();
107 if (props != null) {
108 Enumeration e = props.propertyNames();
109 while (e.hasMoreElements()) {
110 String name = (String) e.nextElement();
111 Element propElement = doc.createElement(PROPERTY);
112 propElement.setAttribute(ATTR_NAME, name);
113 propElement.setAttribute(ATTR_VALUE, props.getProperty(name));
114 propsElement.appendChild(propElement);
115 }
116 }
117 }
118
119 /***
120 * The whole testsuite ended.
121 */
122 public void endTestSuite(JUnitTest suite) throws BuildException {
123 rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount());
124 rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount());
125 rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount());
126 rootElement.setAttribute(ATTR_TIME, "" + (suite.getRunTime() / 1000.0));
127 if (out != null) {
128 Writer wri = null;
129 try {
130 wri = new BufferedWriter(new OutputStreamWriter(out, "UTF8"));
131 wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
132 (new DOMElementWriter()).write(rootElement, wri, 0, " ");
133 wri.flush();
134 } catch (IOException exc) {
135 throw new BuildException("Unable to write log file", exc);
136 } finally {
137 if (out != System.out && out != System.err) {
138 if (wri != null) {
139 try {
140 wri.close();
141 } catch (IOException e) {
142
143 }
144 }
145 }
146 }
147 }
148 }
149
150 /***
151 * Interface TestListener.
152 *
153 * <p>A new Test is started.
154 */
155 public void startTest(Test t) {
156 testStarts.put(t, new Long(System.currentTimeMillis()));
157 }
158
159 /***
160 * Interface TestListener.
161 *
162 * <p>A Test is finished.
163 */
164 public void endTest(Test test) {
165
166
167
168 if (!testStarts.containsKey(test)) {
169 startTest(test);
170 }
171
172 Element currentTest = null;
173 if (!failedTests.containsKey(test)) {
174 currentTest = doc.createElement(TESTCASE);
175 currentTest.setAttribute(ATTR_NAME,
176 JUnitVersionHelper.getTestCaseName(test));
177
178
179 currentTest.setAttribute(ATTR_CLASSNAME,
180 test.getClass().getName());
181 if (test instanceof Documented) {
182 Documented documented = (Documented)test;
183 System.out.println("handle Documented : "+ JUnitVersionHelper.getTestCaseName(test));
184 String javadocData = documented.getMethodDoc(JUnitVersionHelper.getTestCaseName(test));
185 if (javadocData != null && !javadocData.trim().equals("")) {
186 Element nested = doc.createElement(JAVADOC);
187 currentTest.appendChild(nested);
188 nested.appendChild(doc.createCDATASection(javadocData));
189 }
190 } else {
191 System.out.println(test.getClass().getName()+" is no instance of Documented");
192 }
193 rootElement.appendChild(currentTest);
194 testElements.put(test, currentTest);
195
196 } else {
197 currentTest = (Element) testElements.get(test);
198 }
199
200 Long l = (Long) testStarts.get(test);
201 currentTest.setAttribute(ATTR_TIME,
202 "" + ((System.currentTimeMillis() - l.longValue()) / 1000.0));
203 }
204
205 /***
206 * Interface TestListener for JUnit <= 3.4.
207 *
208 * <p>A Test failed.
209 */
210 public void addFailure(Test test, Throwable t) {
211 formatError(FAILURE, test, t);
212 }
213
214 /***
215 * Interface TestListener for JUnit > 3.4.
216 *
217 * <p>A Test failed.
218 */
219 public void addFailure(Test test, AssertionFailedError t) {
220 addFailure(test, (Throwable) t);
221 }
222
223 /***
224 * Interface TestListener.
225 *
226 * <p>An error occurred while running the test.
227 */
228 public void addError(Test test, Throwable t) {
229 formatError(ERROR, test, t);
230 }
231
232 private void formatError(String type, Test test, Throwable t) {
233 if (test != null) {
234 endTest(test);
235 failedTests.put(test, test);
236 }
237
238 Element nested = doc.createElement(type);
239 Element currentTest = null;
240 if (test != null) {
241 currentTest = (Element) testElements.get(test);
242 } else {
243 currentTest = rootElement;
244 }
245
246 currentTest.appendChild(nested);
247
248 String message = t.getMessage();
249 if (message != null && message.length() > 0) {
250 nested.setAttribute(ATTR_MESSAGE, t.getMessage());
251 }
252 nested.setAttribute(ATTR_TYPE, t.getClass().getName());
253
254 String strace = JUnitTestRunner.getFilteredTrace(t);
255 Text trace = doc.createTextNode(strace);
256 nested.appendChild(trace);
257 }
258
259 private void formatOutput(String type, String output) {
260 Element nested = doc.createElement(type);
261 rootElement.appendChild(nested);
262 nested.appendChild(doc.createCDATASection(output));
263 }
264
265 }