我使用PHPUnit在我的Gitlab CI服务器上执行单元测试。当没有执行测试时,构建传递尽管可能存在错误(例如自动加载器问题)。
如果没有执行测试,有没有办法告诉PHPUnit Command Line Runner它应该以代码1退出?
答案 0 :(得分:4)
如果没有测试,那么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,则退出状态将为0然后我们在我们自己的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
我们所追求的是 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