-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A custom JUnit test runner has been added to capture test results and generate XML reports. Ticket #36
- Loading branch information
Showing
4 changed files
with
283 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
233 changes: 233 additions & 0 deletions
233
pki/base/common/test/com/netscape/test/TestListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
package com.netscape.test; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.PrintStream; | ||
import java.net.InetAddress; | ||
import java.text.DateFormat; | ||
import java.text.SimpleDateFormat; | ||
import java.util.Date; | ||
import java.util.TimeZone; | ||
|
||
import javax.xml.parsers.DocumentBuilder; | ||
import javax.xml.parsers.DocumentBuilderFactory; | ||
import javax.xml.transform.OutputKeys; | ||
import javax.xml.transform.Transformer; | ||
import javax.xml.transform.TransformerFactory; | ||
import javax.xml.transform.dom.DOMSource; | ||
import javax.xml.transform.stream.StreamResult; | ||
|
||
import org.junit.runner.Description; | ||
import org.junit.runner.Result; | ||
import org.junit.runner.notification.Failure; | ||
import org.junit.runner.notification.RunListener; | ||
|
||
import org.w3c.dom.CDATASection; | ||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
import org.w3c.dom.Text; | ||
|
||
public class TestListener extends RunListener { | ||
|
||
DateFormat dateFormat; | ||
|
||
DocumentBuilderFactory docBuilderFactory; | ||
DocumentBuilder docBuilder; | ||
Document document; | ||
|
||
TransformerFactory transFactory; | ||
Transformer trans; | ||
|
||
String reportsDir; | ||
|
||
Element testSuiteElement; | ||
long testSuiteStartTime; | ||
|
||
Element testCaseElement; | ||
long testCaseStartTime; | ||
|
||
String currentTestSuiteName; | ||
|
||
long testCount; | ||
long successCount; | ||
long failureCount; | ||
|
||
PrintStream stdOut; | ||
PrintStream stdErr; | ||
|
||
ByteArrayOutputStream out; | ||
ByteArrayOutputStream err; | ||
|
||
public TestListener() throws Exception { | ||
|
||
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); | ||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); | ||
|
||
docBuilderFactory = DocumentBuilderFactory.newInstance(); | ||
docBuilder = docBuilderFactory.newDocumentBuilder(); | ||
|
||
transFactory = TransformerFactory.newInstance(); | ||
trans = transFactory.newTransformer(); | ||
trans.setOutputProperty(OutputKeys.INDENT, "yes"); | ||
|
||
reportsDir = System.getProperty("junit.reports.dir"); | ||
} | ||
|
||
public void testRunFinished(Result result) throws Exception { | ||
if (currentTestSuiteName != null) { | ||
finishTestSuite(); // finish last suite | ||
} | ||
} | ||
|
||
public void testStarted(Description description) throws Exception { | ||
|
||
String testSuiteName = description.getClassName(); | ||
|
||
if (currentTestSuiteName == null) { | ||
startTestSuite(testSuiteName); // start first suite | ||
|
||
} else if (!currentTestSuiteName.equals(testSuiteName)) { | ||
finishTestSuite(); // finish old suite | ||
startTestSuite(testSuiteName); // start new suite | ||
} | ||
|
||
currentTestSuiteName = testSuiteName; | ||
|
||
startTestCase(description); | ||
} | ||
|
||
public void testFinished(Description description) throws Exception { | ||
finishTestCase(); | ||
recordTestCaseSuccess(); | ||
} | ||
|
||
public void testFailure(Failure failure) throws Exception { | ||
finishTestCase(); | ||
recordTestCaseFailure(failure); | ||
} | ||
|
||
public void startTestSuite(String testSuiteName) throws Exception { | ||
|
||
testSuiteStartTime = System.currentTimeMillis(); | ||
|
||
document = docBuilder.newDocument(); | ||
|
||
// test suite | ||
testSuiteElement = document.createElement("testsuite"); | ||
document.appendChild(testSuiteElement); | ||
|
||
testSuiteElement.setAttribute("name", testSuiteName); | ||
testSuiteElement.setAttribute("timestamp", | ||
dateFormat.format(new Date(testSuiteStartTime))); | ||
testSuiteElement.setAttribute("hostname", | ||
InetAddress.getLocalHost().getHostName()); | ||
|
||
// system properties | ||
Element propertiesElement = document.createElement("properties"); | ||
testSuiteElement.appendChild(propertiesElement); | ||
|
||
for (String name : System.getProperties().stringPropertyNames()) { | ||
Element propertyElement = document.createElement("property"); | ||
propertyElement.setAttribute("name", name); | ||
propertyElement.setAttribute("value", System.getProperty(name)); | ||
propertiesElement.appendChild(propertyElement); | ||
} | ||
|
||
// reset counters | ||
testCount = 0; | ||
successCount = 0; | ||
failureCount = 0; | ||
|
||
// redirect outputs | ||
stdOut = System.out; | ||
out = new ByteArrayOutputStream(); | ||
System.setOut(new PrintStream(out, true)); | ||
|
||
stdErr = System.err; | ||
err = new ByteArrayOutputStream(); | ||
System.setErr(new PrintStream(err, true)); | ||
} | ||
|
||
public void finishTestSuite() throws Exception { | ||
|
||
double time = (System.currentTimeMillis() - testSuiteStartTime) / 1000.0; | ||
testSuiteElement.setAttribute("time", "" + time); | ||
|
||
// save counters | ||
long errorCount = testCount - successCount - failureCount; | ||
|
||
testSuiteElement.setAttribute("tests", "" + testCount); | ||
testSuiteElement.setAttribute("failures", "" + failureCount); | ||
testSuiteElement.setAttribute("errors", "" + errorCount); | ||
|
||
// save outputs | ||
System.setOut(stdOut); | ||
System.setErr(stdErr); | ||
|
||
Element systemOutElement = document.createElement("system-out"); | ||
testSuiteElement.appendChild(systemOutElement); | ||
|
||
systemOutElement.appendChild( | ||
document.createCDATASection(out.toString()) | ||
); | ||
|
||
Element systemErrElement = document.createElement("system-err"); | ||
testSuiteElement.appendChild(systemErrElement); | ||
|
||
systemErrElement.appendChild( | ||
document.createCDATASection(err.toString()) | ||
); | ||
|
||
// write to file | ||
FileWriter fw = new FileWriter( | ||
reportsDir + File.separator + "TEST-" + currentTestSuiteName + ".xml" | ||
); | ||
StreamResult sr = new StreamResult(fw); | ||
DOMSource source = new DOMSource(document); | ||
trans.transform(source, sr); | ||
fw.close(); | ||
} | ||
|
||
public void startTestCase(Description description) throws Exception { | ||
|
||
testCaseStartTime = System.currentTimeMillis(); | ||
|
||
testCaseElement = document.createElement("testcase"); | ||
testSuiteElement.appendChild(testCaseElement); | ||
|
||
testCaseElement.setAttribute("classname", description.getClassName()); | ||
testCaseElement.setAttribute("name", description.getMethodName()); | ||
|
||
testCount++; | ||
} | ||
|
||
public void finishTestCase() throws Exception { | ||
double time = (System.currentTimeMillis() - testCaseStartTime) / 1000.0; | ||
testCaseElement.setAttribute("time", "" + time); | ||
} | ||
|
||
public void recordTestCaseSuccess() throws Exception { | ||
successCount++; | ||
} | ||
|
||
public void recordTestCaseFailure(Failure failure) throws Exception { | ||
|
||
Element failureElement = document.createElement("failure"); | ||
testCaseElement.appendChild(failureElement); | ||
|
||
Description description = failure.getDescription(); | ||
String exceptionName = failure.getException().getClass().getName(); | ||
|
||
failureElement.setAttribute("message", failure.getMessage()); | ||
failureElement.setAttribute("type", exceptionName); | ||
|
||
Text messageElement = document.createTextNode( | ||
exceptionName + ": " +failure.getMessage() + "\n\tat " + | ||
description.getClassName() + "." + description.getMethodName() + "()" | ||
); | ||
failureElement.appendChild(messageElement); | ||
|
||
failureCount++; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.netscape.test; | ||
|
||
import org.junit.internal.RealSystem; | ||
import org.junit.runner.JUnitCore; | ||
import org.junit.runner.Result; | ||
|
||
public class TestRunner { | ||
|
||
public Result run(String... args) throws Exception { | ||
|
||
JUnitCore core = new JUnitCore(); | ||
core.addListener(new TestListener()); | ||
|
||
return core.runMain(new RealSystem(), args); | ||
} | ||
|
||
public static void main(String... args) throws Exception { | ||
|
||
TestRunner runner = new TestRunner(); | ||
Result result = runner.run(args); | ||
System.exit(result.wasSuccessful() ? 0 : 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters