之前写过一个关于怎样生成 html 的东西,当时是通过 java 代码去解析生成的 xml 然后再拼装成 html,感觉那个方法不是很好,太繁琐,后来看到 java 可以利用 ant 来生成 html,于是就试了一下。虽然很不愿意去看 ant 的资料,在各位大神严厉的不严厉的批评下还是硬着头皮大致过了一遍,觉得实现方法比较低端就没写贴,看到今天有小伙伴需要就贴一下,献个丑。
如下为 build.xml 的片断
<target name="test" depends="compile">
<mkdir dir="report" />
<junit printsummary="yes" haltonerror="no" haltonfailure="no" fork="yes">
<formatter type="plain" usefile="false" />
<formatter type="xml" />
<test name="com.xxx.TestAll" todir="report" />
<!--<classpath>
<pathelement location="bin" />
<fileset dir="${lib.dir}" includes="*.jar" />
</classpath>-->
<classpath refid="classpath.test" />
</junit>
</target>
<target name="report" depends="test">
<mkdir dir="report/html" />
<junitreport todir="report">
<fileset dir="report">
<include name="TEST-*.xml" />
</fileset>
<report todir="report/html" />
</junitreport>
</target>
但是问题来了,在 android 代码的 build.xml 文件中通过来执行测试程序总会报 Stub!
TestAll:
[mkdir] Created dir: E:\git-temp\junit
[junit] Exception in thread "main" java.lang.RuntimeException: Stub!
[junit] at junit.framework.TestResult.<init>(TestResult.java:4)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.IgnoredTestResult.<init>(IgnoredTestResult.java:41)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:356)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1179)
[junit] at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:1030)
查了一下
可能不是这个原因,知道原因的还请不吝赐教。
于是决定不用<junit>
来执行测试程序。换成执行命令行的方式继续配合<junitreport >
来执行,<junitreport >
是通过 XSL 将 xml 自动转换成 xml,它会自动生成一个 TESTS-TestSuites.xml,它是所有测试结果的一个汇总,html 文件夹中的 index.xml 就是根据它来显示的。
可以先看一下效果,不嫌丑的可以继续往下看 (这么丑的东西,大神就先闭眼略过吧)
因为执行速度慢,我只跑了一个包,没有跑全部
在 jenkins 上用 publish html report 把路径选么 html 就可以实现报告展示。
接下来上代码,边讲边上,由于很少写东西,看不明白的继续问就好。
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="testing_internal" default="junitreport">
<property file="ant.properties" />
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<import file="custom_rules.xml" optional="true" />
<import file="${sdk.dir}/tools/ant/build.xml" />
<target name="cleanReport">
<delete dir="${junit.output.dir}"></delete>
</target>
<!-- 执行测试 -->
<target name="test" depends="cleanReport">
<xpath input="${tested.project.dir}/AndroidManifest.xml"
expression="/manifest/@package" output="tested.package"/>
<echo>Running tests...</echo>
<exec executable="${adb}" failonerror="true">
<arg line="${adb.device.arg}"/>
<arg value="shell"/>
<arg value="am"/>
<arg value="instrument"/>
<arg value="-w"/>
<arg value="${tested.package}/${test.runner}"/>
</exec>
</target>
<!-- pull -->
<target name="pull" depends="test">
<echo>Downloading XML test report...</echo>
<mkdir dir="${junit.output.dir}"/>
<exec executable="${adb}" failonerror="true">
<arg line="${adb.device.arg}"/>
<arg value="pull" />
<arg value="/sdcard/KTJunitTestReport/"/>
<arg value="${junit.output.dir}/" />
</exec>
</target>
<target name="junitreport" depends="pull">
<!-- 生成报告-->
<junitreport todir="${junit.output.dir}">
<fileset dir="${junit.output.dir}">
<include name="*-TEST.xml"/>
</fileset>
<report format="frames" todir="${junit.output.dir}/html"/>
</junitreport>
</target>
</project>
为习惯性伸手党们考虑,把 properties 文件也贴一下吧,虽然这种伸手习惯不太好,但慢慢消化变成自己的就好
ant.properties
tested.project.dir=../ktplay_testing_internal
junit.report.dir=../ktplay_testing_internal
jar.libs=${junit.report.dir}/libs
junit.output.dir=junit-report
test.runner=com.ktplay.testing.PolideaInstrumentationTestRunner
teste.package=com.ktplay.sample
src.dir=src
tested.package=com.ktplay.testing.internal
至于 build.xml 文件我都在重要的地方加了注释,看起来应该不难。
紧接着问题又来了,test.runner 里边的类是哪儿来的?为什么要用它?
1.从哪儿来
这个类是我从https://code.google.com/p/the-missing-android-xml-junit-test-runner/
这个 jar 需要自己改一下,链接里对使用方法也有讲述,也可以找到源码,我在源码的基础上自己小小改动了一下,
之所以要改是因为它生成的 xml 会自己包一个根节点,导致我生成的汇总 TESTS-TestSuites.xml 总是 0kb,去掉就好了,还有一个原因是它生成的报告是写系统文件放入 data/dta/com.xxx.xxx./files/,如果我连没有 root 的手机则无法写入。改完的代码就不发了,大家可以自行下载,根据自己需要去修改。
2.为什么要用它
我试过 junit-report.jar 包,但通过 XSL 总是不能把它生成的 xml 报告转换出来,我觉得可能还是节点名什么的不对应,具体内部实现我也不清楚。
但 PolideaInstrumentationTestRunner 这个类确解决了这一点。
至此重要的环节已经贴完,开始让它跑起来吧。。
可能有些地方写的不是很明白,也不太好,如果哪儿写的不正确还请各位大神指摘点评,像我一相的菜鸟可以尽情提问。