背景
每天都会收到自动化测试报告,如果报告中某几个用例执行失败了,假设就是开发的bug,开发做了修复,这时你需要快速验证下开发是否真的修复,那么我可能就想直接通过测试报告中去触发运行某个具体的case。
思路实现
那这里我就以Allure 2的测试报告给大家一个简单的实现思路:测试报告中在具体的测试用例中某个地方点击下,那么能在Jenkins中触发对应的脚本用例运行。
那想测试报告中触发Jenkins跑,那就意味着Jenkins需要提供一个 API给测试报告对吧,而且API还能确定具体要运行的测试用例对吧。
OK,那解决Jenkins外部调用的API,这时我们查文档大体都能查到有个这么个api信息:
http://jenkins url/jenkins/job/job name/buildWithParameters?Submit=Build&token=xxxxxx&xxx=xxxx
就是我们可以通过给Jenkins Job配置一个token,来调用,同时跟上一些你Jenkins 已经配置好的参数来动态话请求参数。这时,我想你应该意识到,如果我们这个参数是类名+方法名是不是基本可以确定了我们具体要执行的那个用例脚本。 OK,居于这个我们就给Jenkins新建一个Job用来单独跑某个具体的case,同时把Case的类目和方法名参数化掉,最后大概如下截图:
创建一个token
调用jenkins api时,带上token ,className等参数,这样job就拿到参数了。 拿到参数后,我们得动态修改下TestNG的 run xml文件,因为毕竟最终是通过这个xml来确定要执行的case,那么我们编写下run的xml文件,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<!--配置Case集合名 并发方式tests 和并发数-->
<suite name="All Test" parallel="tests" thread-count="1">
<parameter name="env" value="${env}"/>
<parameter name="platform" value="${platform}"/>
<test name="自动化测试" annotations="JDK">
<classes>
<class name="classPath">
<methods>
<include name="methodName"></include>
</methods>
</class>
</classes>
</test>
<listeners>
<!--重跑机制-->
<listener class-name="com.lucky.common.testng.RetryListener"/>
<listener class-name="com.lucky.common.testng.TestResultListener"/>
</listeners>
</suite>
然后想办法 在Jenkins 运行之前,修改掉这份xml 里面的 classPath 和 methodName,所以我们Jenkins 配置添加大概如下脚本,用于动态修改xml,其中classPath methodName 都从参数获取到值:
cd $WORKSPACE/src/test/runxml/OneCase
CLASS_NAME=${className}
METHOD_NAME=${methodName}
echo ’开始修改xml文件。。。。。。‘
sed -i 's/classPath/'$CLASS_NAME'/g' RunOneCase.xml
sed -i 's/methodName/'$METHOD_NAME'/g' RunOneCase.xml
echo ’修改结束!!!!!!‘
cat RunOneCase.xml
OK 到这里我们完成了完整的从Jenkins API 调用触发具体某个case运行。那下一步就得在测试报告中加入 调用这个API的方式,我们对Allure报告做一个扩展。
Allure 2是支持往测试报告里面插入附件的,所以思路就这边,那么我们插入一个 html 会怎么样,并插入一段JavaScript 貌似就能解决问题了。 那我们就根据这个思路,编写一个Html文件,并作为附件插入到Allure 2的测试报告中。
@Attachment(value = "单独重跑", type = "text/html")
public static String reRunUrl(String className, String methodName, String sendEmail) {
BaseData baseData = BaseDataUtils.getBaseData();
String env = baseData.getEnv();
String url = "";
if (FinalText.ENV_TEST.equals(env)) {
url = FinalText.JENKINS_TEST + "className=" + className + "&methodName=" + methodName + "&sendEmail=" + sendEmail;
} else if (FinalText.ENV_PRE.equals(env)) {
url = FinalText.JENKINS_PRE + "className=" + className + "&methodName=" + methodName + "&sendEmail=" + sendEmail;
}
return html(url, className, methodName);
}
private static String html(String url, String className, String methodName) {
String html = "<html>\n" +
"<head>\n" +
" <script language=\"javascript\">\n" +
" function print() {\n" +
" var a = myform.email.value;\n" +
" window.open(`" + url + "`+a,'_blank').location;\n" +
" }\n" +
" </script>\n" +
"</head>\n" +
"<body>\n" +
" <h4>手动运行该用例,点击运行后请等待结果发送到邮箱</h4>\n" +
" <h4>类名:" + className + " 方法名:" + methodName + "</h4>\n" +
" <form name=\"myform\">\n" +
" 结果接收邮箱: <input type=\"text\" name=\"email\" id=\"email\" size=\"30\"/>\n" +
" <input type=\"button\" name=\"button\" value=\"运 行(不要重复点击)\" onclick=\"print()\" />\n" +
" </form>\n" +
"</body>\n" +
"</html>";
return html;
}
代码如上,我就不一一详解代码意思了,最后看下展示效果:
这样,我们如果要重跑该case,只要输入接受的邮箱地址,点击run ,那么就调用了Jenkins Job 执行对应的用例脚本。