如果不执行测试,PHPUnit 就会失败

问题描述 投票:0回答:2

我使用 PHPUnit 在我的 Gitlab CI 服务器上执行单元测试。当没有执行测试时,构建通过,但可能会出现错误(例如自动加载器问题)。

有没有办法告诉 PHPUnit 命令行运行程序,如果没有执行测试,它应该以代码 1 退出?

php phpunit gitlab
2个回答
4
投票

如果没有测试,PHPUnit 就无法将任何内容标记为失败。因此,PHPUnit 无法做到这一点。您可以使用 Sebastian Bergmann 的另一个工具phploc

这有一个

--count-tests
选项。在运行
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
评估的结果,该结果为 false,导致状态码为 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

0
投票

有没有办法告诉 PHPUnit 命令行运行程序,如果没有执行测试,它应该以代码 1 退出?

跑步者已经通过

test-results
哨兵文件(默认启用)告知。

引导程序可以注册关闭函数 1,然后通过检查

test-results
文件来检查已运行的测试数量(或者如果有的话)。

它是 JSON 文本。在引导程序开始时取消链接文件:

@unlink('test-results');

如果没有测试,则检查关闭功能并退出:²

empty(@json_decode(file_get_contents('test-results'))->times)
&& trigger_error('test-results: no tests executed', E_USER_ERROR);

参见。 PHPUnit 的

bootstrap
cacheDirectory
cacheResult
9.6
cacheResultFile
属性。


1

register_shutdown_function()
,参见。 https://php.net/register_shutdown_function说明:register_shutdown_function

² 关于退出状态代码的注意事项:A

trigger_error(..., E_USER_ERROR)
召唤退出代码 255 — PHP 致命错误 — 使用
exit(1)
获得最小退出代码 1,此时不会覆盖更高的退出代码。

© www.soinside.com 2019 - 2024. All rights reserved.