【发布时间】:2017-03-18 05:33:30
【问题描述】:
我使用 PHPUnit 在我的 Gitlab CI 服务器上执行单元测试。如果未执行任何测试,则构建通过可能会出现错误(例如自动加载器问题)。
如果没有执行任何测试,有没有办法告诉 PHPUnit Command Line Runner 它应该以代码 1 退出?
【问题讨论】:
我使用 PHPUnit 在我的 Gitlab CI 服务器上执行单元测试。如果未执行任何测试,则构建通过可能会出现错误(例如自动加载器问题)。
如果没有执行任何测试,有没有办法告诉 PHPUnit Command Line Runner 它应该以代码 1 退出?
【问题讨论】:
如果没有测试,PHPUnit 将无法将任何内容标记为失败。因此,PHPUnit 无法做到这一点。你可以使用的是 Sebastian Bergmann 的另一个工具phploc。
这里有a --count-tests option。在运行 phpunit 之前运行它,处理结果,如果计数为 0,则只需来自脚本的 exit 1。
更新,我刚刚意识到我错过了早点做的明显事情。
一个简单的方法是:
count=$(./phploc.phar --count-tests src | awk '/Tests/{getline; print}' | awk '{print $NF}') && [ "${count}" -ne "0" ]
exit $?
下面的大部分命令分解都适用,所以我保持原样。主要区别在最后:
[ "${count}" -ne "0" ]
exit $?
这基本意思是:比较${count}和0,如果不匹配0,比较退出状态为0,如果为0,退出状态为1。然后我们简单的复用退出状态在我们自己的exit 声明中:exit $? 基本上是在说:以与我们最后做的事情相同的退出状态退出。
获取您要查找的退出状态的简单命令可以使用以下命令获得:
count=$(./phploc.phar --count-tests src | awk '/Tests/{getline; print}' | awk '{print $NF}') && [ "${count}" -eq "0" ] && exit 1 || exit 0
稍微分解一下:
./phploc.phar --count-tests src
这基本上在 src 目录上运行 phploc,输出将包含一个类似于以下内容的部分:
Tests
classes 123
methods 1234
我们所追求的是 after Tests 这一行。所以命令的输出被传递给 awk,它将匹配Tests,获取下一行并打印它(即:classes 123)。这发生在这里:
| awk '/Tests/{getline; print}'
该字符串再次传递给 awk,以提取最后一部分(找到的实际测试数):
awk '{print $NF}'
该值将分配给count,因为我们正在运行以下命令:
count=$(phploc | awk | awk)
所以最终输出分配给count。接下来,我们要查看测试计数是否为零,基于此我们需要以零或非零状态退出。这是我们可以轻松做到的事情:
[ "${count}" -eq "0" ] && exit 1 || exit 0
这基本上是以下的简写:
if [ "${count}" -eq "0" ]; then
exit 1
else
exit 0
fi
这要归功于短路评估:如果 [ "${count}" -eq "0" ] 评估为 true,则需要评估 && 子句,这是一个 exit 1 语句,返回所需的非零退出代码
如果我们省略|| exit 0,最后一个状态码将是[ "${count}" -eq "0" ] && exit 1评估的结果,这是错误的,导致状态码为1。为了避免这种情况,我们必须添加|| exit 0 .
您可以通过在 CLI 上编写类似的内容来轻松检查:
foo="bar" && [ "${foo}" -eq "123" ] && echo 'foo matched 123'
//run this, then run
echo $?
输出将为 1(最后一个命令的退出状态)
如果单元测试的运行时间不超过几分钟,并且您不关心运行两次,则可以检查 phpunit 的输出。在删除测试目录后,我很快尝试在我正在处理的项目之一上运行 phpunit 5.4.6。输出是这样的:
PHPUnit 5.4.6 by Sebastian Bergmann and contributors.
Time: 51 ms, Memory: 8.50MB
No tests executed!
所以运行:
vendor/bin/phpunit | grep -q 'No tests executed'
如果没有测试,则返回退出状态 0,如果有,则返回 1。只需检查退出状态并使用相反的代码退出。这样的事情可能有效:
vendor/bin/phpunit | grep -q 'No tests executed' && exit 1 || exit 0
【讨论】:
--fail-on-no-tests 和退出代码 1。