【发布时间】:2020-01-07 15:26:56
【问题描述】:
jenkins 测试结果 GUI 将 skipped 或 expectedFail 测试显示为已跳过。 跳过或预期失败测试的单独测试视图显示“跳过消息”和“标准输出”
例如“跳过的消息”可以是:
-
自定义跳过消息
* e.g. from python @unittest.skip("some reason") tag or * e.g. raise unittest.SkipTest("thing not found.") - “预期测试失败”
- “xfail-marked 测试意外通过”
我们正在使用 groovy 脚本生成测试报告。 我们希望包含更多关于跳过测试的信息,而不仅仅是“跳过”。 我们如何在 GUI 视图中的“已跳过消息”中获取有关已跳过测试的信息?
jenkins API 记录在这里:
https://javadoc.jenkins.io/plugin/junit/hudson/tasks/junit/TestResult.html
没有具体要求获取有关已跳过或预期失败测试的信息。 我希望通过一些实验,可以通过这个 testResult API 获得 expectedFail 信息。 从这些 API 调用开始:
String getErrorDetails()
If there was an error or a failure, this is the text from the message.
String getErrorStackTrace()
If there was an error or a failure, this is the stack trace, or otherwise null.
String getName()
Gets the name of this object.
String getStderr()
The stderr of this test.
String getStdout()
The stdout of this test.
TestResult getTestResult()
Returns the top level test result data.
String getTitle()
Gets the human readable title of this result object.
在图形用户界面中:
- 正常通过的测试只有“标准输出”。
- 正常失败的测试有“错误消息”、“堆栈跟踪”和“标准输出”。
- 跳过或预期失败测试显示“跳过消息”和“标准输出”。
我们正在使用 python unittest 输出 junit 测试结果文件。 使用 junit 测试结果插件将其加载到 jenkins 中。
我是否错过了 jenkins 测试结果 API 中的某些内容,这些内容可以提供有关预期失败或跳过测试的更多信息? 我希望通过使用 API 的实验找到信息。 并将其记录在此处的答案中。
这里是测试报告 groovy 脚本的内容 (在 jenkins 中使用 Execute Groovy Script 插件 在 jUnit 结果插件收获测试结果后):
import hudson.model.*
def build = Thread.currentThread().executable
workspace = build.getEnvVars()["WORKSPACE"]
reportfilename = workspace + "/testreport.html"
rf = new File(reportfilename);
def testCount = "0"
def testPassed = "0"
def testFailed = "0"
def testSkipped = "0"
def buildDuration = "0"
def workspace = "unknown"
def buildName = "unknown"
def BUILD_STATUS = ""
def BUILD_URL = ""
def testResult = null
def testResult1 = null
def testResult2 = null
def testDuration = ""
def caseResult = null
def buildNumber = 0
def buildNumHash = ""
def buildTimeString = ""
def rooturl = ""
try {
buildNumber = build.number
buildNumHash = build.getDisplayName()
//currentBuildNumber = manager.build.number
buildTimeString = build.getTime().format("YYYY-MMM-dd HH:mm:ss")
if(build.testResultAction) {
testResult = build.testResultAction
testCount = String.format("%d",(testResult.totalCount))
testPassed = String.format("%d",(testResult.result.passCount))
testFailed = String.format("%d",(testResult.result.failCount))
testSkipped = String.format("%d",(testResult.result.skipCount))
testDuration = String.format("%.2f",(testResult.result.duration ))
}
workspace = build.getEnvVars()["WORKSPACE"]
buildName = build.getEnvVars()["JOB_NAME"]
BUILD_STATUS = build.getEnvVars()["BUILD_STATUS"]
BUILD_URL = build.getEnvVars()["BUILD_URL"]
testResult1 = hudson.tasks.junit.TestResult
testResult2 = build.getAction(hudson.tasks.junit.TestResultAction.class)
caseResult = hudson.tasks.junit.CaseResult
rooturl = manager.hudson.rootUrl
} catch(Exception ex) {
rf << "exception accessing build.testResultAction object.";
//rf << ex;
}
// in groovy the write RE-creates the file, rf << "whatever" is used to append.
rf.write "<html><head><title>testreport.groovy #$buildNumber $buildName</title></head><body>"
rf << "Summary test report <br><br>\n\
<b>TEST RESULT:</b> $testCount total, <b>$testPassed pass</b>, <b>$testFailed fail</b>, $testSkipped skip.<br>\n\
Workspace : $workspace<br>\n\
Project Name : $buildName $buildNumHash<br><br>\n\
"
if (build) {
rf << """<!-- GENERAL INFO -->\n\
\n\
<TABLE>\n\
<TR><TD align=\"right\">\n\
<j:choose>\n\
<j:when test=\"${build.result=='SUCCESS'}\">\n\
<IMG SRC=\"${rooturl}static/e59dfe28/images/32x32/blue.gif\" />\n\
</j:when>\n\
<j:when test=\"${build.result=='FAILURE'}\">\n\
<IMG SRC=\"${rooturl}static/e59dfe28/images/32x32/red.gif\" />\n\
</j:when>\n\
<j:otherwise>\n\
<IMG SRC=\"${rooturl}static/e59dfe28/images/32x32/yellow.gif\" />\n\
</j:otherwise>\n\
</j:choose>\n\
</TD><TD valign='center'><B style='font-size: 200%;'>BUILD ${build.result}</B></TD></TR>\n\
<TR><TD>Build URL</TD><TD><A href=\"${rooturl}${build.url}\">${rooturl}${build.url}</A></TD></TR>\n\
<TR><TD>Project:</TD><TD>${buildName}</TD></TR>\n\
<TR><TD>Date of build:</TD><TD>${buildTimeString}</TD></TR>\n\
<TR><TD>Build duration:</TD><TD>${build.durationString}</TD></TR>\n\
<TR><TD>Test duration:</TD><TD>${testDuration}</TD></TR>\n\
</TABLE>\n\
<BR/>\n\
"""
}
if(!testResult) {
rf << "<br>No test result<br>"
rf << "</body></html>"
return ("No test result")
}
def junitResultList = [];
junitResultList.add(testResult.getResult())
if (junitResultList.size() > 0) {
rf << "<br>test result from build.testResultAction"
} else {
junitResultList.add(testResult2.getResult())
if (junitResultList.size() > 0) {
rf << "<br>test result from build.getAction"
} else {
rf << "<br>No results in 'testResult2'<br>\n"
junitResultList.add(testResult1.getResult())
}
}
//rf << "<br>DEBUG" + junitResultList.size() + " test items"
// API: http://hudson-ci.org/javadoc/hudson/tasks/junit/PackageResult.html
rf << "<!-- JUnit TEMPLATE: all tests PASS FAIL SKIP -->\n"
if (junitResultList.size() > 0) {
rf << '<TABLE width="100%">\n'
rf << "<TR><TD class='bg1' colspan='2'><B>${junitResultList.first().displayName}</B></TD></TR>\n"
junitResultList.each { junitResult ->
junitResult.getChildren().each { packageResult ->
rf << "<TR><TD class='bg2' colspan='2'> <B>TEST SUITE: ${packageResult.getName()} Failed: ${packageResult.getFailCount()} test(s), Passed: ${packageResult.getPassCount()} test(s)</B>, Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)</TD></TR>\n"
packageResult.getChildren().each { suite ->
suite.getChildren().each { test ->
def colour = "lightgreen"
def highlight1=""
def highlight2=""
RESULT = test.getStatus().name() // FAILED or PASSED or SKIPPED (.name() not .value)
// hudson.tasks.junit.CaseResult.Status.FAILED
if (RESULT == "FAILED" || RESULT == "REGRESSION") {
colour = "#ffcccc"
highlight1="<B>"
highlight2="</B>"
}
if (RESULT == "SKIPPED") { colour = "#ffffb3" }
rf << "<TR bgcolor='${colour}'><TD class='test' colspan='2'>${highlight1}<li>${RESULT}: ${test.getFullName()} </li>${highlight2}</TD></TR>\n"
}
}
}
}
rf << '</TABLE><BR/>\n'
}
rf << "testreport.groovy</body></html>\n"
【问题讨论】:
标签: jenkins groovy junit test-reporting