从命令行获取通过和失败测试的数量

Get the number of passed and failed tests with their name from command line

我正在编写 Python 脚本,它将 运行 mvn test 放在不同的文件夹上,我想从脚本中获取通过测试和失败测试的数量及其名称。

现在我已经设法 运行 处理并得到它的输出

proc = subprocess.run(["mvn", "test", "-f", PROJ_PATH])
print(proc.stdout)

输出:

   Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.715 s
[INFO] Finished at: 2016-10-12T18:59:11+03:00
[INFO] Final Memory: 10M/212M
[INFO] ------------------------------------------------------------------------

我知道我可以使用 regexp 并尝试解析输出,但可能有一些更合适的方法可以与来自 Python 或 Bash 的 Maven 合并。

有多种解决方案,但没有直接的解决方案...它们都涉及一些解析(XML 或文本文件)。

XML 报告

这可能是最安全、最简单的路线。 Surefire 默认在 target/surefire-reports. There is one XML file per test class, and this file contains the results of the execution of the tests in that class. This XML follows a pre-defined XSD 内生成 XML 报告并保证稳定输出。

target/surefire-reports 中的每个 XML 文件(对于每个测试 class)被命名为 TEST-${testClass}.xml 其中 ${testClass} 被替换为测试的完全限定名称测试 class。 my.test.MyTest 的测试 class 的相关内容是:

<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="my.test.MyTest" tests="4" errors="1" skipped="1" failures="1">
  <properties> <!-- omitted, contains system properties for the test --> </properties>
  <testcase name="test" classname="my.test.MyTest" time="0.096">
    <failure></failure>
  </testcase>
  <testcase name="test2" classname="my.test.MyTest" time="0.001">
    <error></error>
  </testcase>
  <testcase name="test3" classname="my.test.MyTest" time="0.002"/>
  <testcase name="test4" classname="my.test.MyTest" time="0">
    <skipped/>
  </testcase>
</testsuite>

(还有其他属性,但与这里无关)。基本上,<testsuite> 表示有 4 个测试,导致 1 个错误,1 个失败和 1 个跳过;所以剩下的1个是成功的。更准确地说,每个<testcase>通过name属性代表一个测试方法,里面的元素代表它的结果。关于测试的 4 种可能结果,这可以很简单地解析:

  • 失败(其中的断言未被验证):<testcase>.
  • 里面有一个<failure>元素
  • 错误(抛出异常,没想到):<testcase>.
  • 里面有一个<error>元素
  • 跳过:<testcase>里面有一个<skipped>元素。
  • 成功:<testcase>.
  • 里面没有元素

如果您想要测试方法的完全限定名称,请将 classname 属性(这是测试的限定名称 class)附加到 name 属性(其中是测试方法的名称)。

日志

如果您使用 plain reportFormat

配置 Surefire 插件
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.19.1</version>
  <configuration>
    <reportFormat>plain</reportFormat>
  </configuration>
</plugin>

日志将包含所有需要的信息:

Running my.test.MyTest
Tests run: 4, Failures: 1, Errors: 1, Skipped: 1, Time elapsed: 0.169 sec <<< FAILURE! - in my.test.MyTest
test(my.test.MyTest)  Time elapsed: 0.112 sec  <<< FAILURE!
java.lang.AssertionError
    at my.test.MyTest.test(my.test.MyTest.java:16)

test2(my.test.MyTest)  Time elapsed: 0.001 sec  <<< ERROR!
java.lang.IllegalArgumentException: Exception
    at my.test.MyTest.test2(my.test.MyTest.java:21)

test3(my.test.MyTest)  Time elapsed: 0.002 sec
test4(my.test.MyTest) skipped

然后你可以有很多乐趣用正则表达式来查找这个文件 (.*)\((.*)\)\s+(?|(skipped)|Time elapsed:.*<<< (.*)): 测试的方法名称在组 1 中,完全限定的 class 名称在组 2 和组中3 包含结果;如果第 3 组为空,则成功。