import fr.aerow.opentext.apmclass.ApmTestCase
import org.junit.runner.Description
import org.junit.runner.JUnitCore
import org.junit.runner.notification.Failure
import org.junit.runner.notification.RunListener
import org.junit.runner.notification.RunNotifier
import org.junit.runner.Result
import static groovy.xml.XmlUtil.escapeXml
@groovy.transform.CompileStatic // Use TypeChecked if metaClass is needed
class ApmTestsListenerHtml extends RunListener {
private PrintWriter output
private Map<String,Boolean> allTests // Map of test names and success status
ApmTestsListenerHtml(PrintWriter writer) {
allTests = [:]
output = writer
}
// Called before any tests have been run.
void testRunStarted(Description desc) {
output.println '''\
| <style>
| .apm-testresult-failure details, .apm-testresult-error details {
| cursor: pointer
| }
| .apm-testresult-failure summary, .apm-testresult-error summary {
| display: inline-block;
| border-bottom: 1px dotted darkred;
| }
| </style>
'''.stripMargin()
def numOfTests = desc.testCount()
output.println "<p>Running ${numOfTests} unit test${numOfTests != 1 ? 's' : ''}…</p>"
}
// Called when all tests have finished.
void testRunFinished(Result res) {
output.println "<h2>Unit tests ${res.wasSuccessful() ? 'OK' : 'KO'}"
output.println '<h3>Tests</h3>'
output.println '''\
| <table>
| <thead>
| <tr>
| <th>Method name</th>
| <th>Result</th>
| </tr>
| </thead>
| <tbody>
'''.stripMargin()
allTests.each { name, wasSuccessful ->
output.println """\
| <tr>
| <td>
| <code>${name}</code>
| </td>
| <td>
| <output style="color: ${wasSuccessful ? 'darkgreen' : 'darkred'};">
| ${wasSuccessful ? 'PASSED' : 'FAILED'}
| </output>
| </td>
| </tr>
""".stripMargin()
}
output.println '</tbody></table>'
output.println '<h3>Failures</h3>'
res.failures.each() { Failure fail ->
output.println """\
| <li class='apm-testresult-failure'>
| <details>
| <summary>
| <code>${fail.getTestHeader()}</code>
| </summary>
| <pre><samp>${escapeXml(fail.getTrace())}</samp></pre>
| </details>
| </li>
""".stripMargin()
}
output.println '<h3>Summary</h3>'
def passCount = res.getRunCount() - res.getFailureCount()
output.println "<p>Test results: ${passCount} passed, ${res.getFailureCount()} failed.</p>"
}
// Called when an atomic test is about to be started.
void testStarted(Description desc) {
String methodName = desc.getMethodName()
allTests[methodName] = true
}
// Called when an atomic test has finished, whether the test succeeds or fails.
void testFinished(Description desc) {
// output.println "<p>Test ${desc.getMethodName()} done</p>"
}
// Called when an atomic test fails, or when a listener throws an exception.
void testFailure(Failure fail) {
String methodName = fail.getDescription().getMethodName()
allTests[methodName] = false
//output.println """${fail.getDescription().getMethodName()} <code style="color: darkred;">FAILED</code></li>"""
}
// Called when an atomic test flags that it assumes a condition that is false.
// Such tests should not really be considered “failed” (for example, checking for Windows paths while tests run on Linux)
void testAssumptionFailure(Failure fail) {
// output.print "Failed: ${fail.getDescription().getMethodName()}"
}
// Called when a test will not be run, generally because a test method is annotated with @org.junit.Ignore
void testIgnored(Description desc) {
//output.println "Ignored: ${desc.getMethodName()}"
}
// Called when a test suite is about to be started.
void testSuiteStarted(Description desc) {
// TODO
}
// Called when a test suite has finished, whether the test suite succeeds or fails.
void testSuiteFinished(Description desc) {
// TODO
}
}
/*
** @author Dimitri Torterat
*/
def classToLoad
long testScriptId
try {
testScriptId = Long.parseLong(params.dataId)
} catch (Exception e) {
/*
gui.contentType = 'application/problem+json'
def jsonOutput = JsonOutput.toJson(// See RFC 7807
[
title: 'Bad request – Invalid document identifier',
status: 403,
detail: "params.dataId (${params.dataId}) is invalid. Your URL should contain dataId=123456",
instance: "${params?.myurl}",
])
response.success(jsonOutput, 403)
return
*/
out << "<p><var>params.dataId</var> (<out>${params.dataId}</out>) is invalid. Your URL should contain <var>dataId=123456</var>.</p>"
return
}
try {
classToLoad = docman.runContentScript(testScriptId, binding)
} catch (com.answer.modules.cscript.api.exception.InvalidParamException e) {
out << "<p>Invalid node ID ${testScriptId}.<p>"
out << '<pre>'
printError e
out << '</pre>'
return
}
out.withPrintWriter { writer ->
if (classToLoad && classToLoad in ApmTestCase) {
def apmTestsListener = new ApmTestsListenerHtml(writer)
def runner = new JUnitCore()
runner.addListener(apmTestsListener)
runner.run(classToLoad)
writer.flush()
} else {
writer.println '''<p>No test classes have been found.</p>
<p>Make sure your script contains the word “test” in its name (case-insensitive)
and returns a class extending <code>ApmTestCase</code>.</p>'''
}
}
Comments
0 B
|👍
/👎
0 B
|0 👍
/0 👎
0 B
|👍
/👎