我通过创建与测试文件一样多的缓存目录找到了解决方法。
我定义了 8 个测试套件来适应我的 CPU 的 8 个内核:
<!-- app/phpunit.xml.dist -->
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals = "false"
…
>
…
<testsuites>
<testsuite name="Group1">
<file>../src/AcmeBundle/Tests/Command/CommandTest.php</file>
<file>…</file>
</testsuite>
…
<testsuite name="Group8">
<file>../src/AcmeBundle/Tests/Controller/AdminControllerTest.php</file>
</testsuite>
</testsuites>
</phpunit>
我创建了一个phpunit.sh脚本,它使用export
(正如大卫哈克尼斯所建议的那样,以便为每个测试套件定义一个特定的路径:
#!/bin/bash
function test() {
testsuite=$1
export CACHE_PATH="$testsuite"
OUTPUT=$(phpunit -c app/phpunit.xml.dist --testsuite $testsuite)
RETURN=$?
if [ $RETURN -eq 0 ]
then
echo -e -n "\033[01;32m● OK\t\033[00m \033[01;35m$testsuite\033[00m"
tail=$(echo "$OUTPUT" | tail -n 3)
echo -e "\t\"$tail\"" | tr '\n' '\t' | tr -s '\t'
echo ""
else
echo -e "\033[01;31m❌ ERROR\033[00m \033[01;35m$testsuite\033[00m (\033[01;34m$RETURN\033[00m)\033[00m"
echo "-----"
echo "$OUTPUT"
echo "-----"
fi
}
for testsuite in $(seq 1 8)
do
tester "Group$testsuite" &
done
# http://unix.stackexchange.com/questions/231602/how-to-detect-that-all-the-child-processes-launched-in-a-script-ended/231608#231608
wait
echo "Done"
如果一切正常,成功的测试套件会以绿色标记显示,并且 phpunit 的输出将被截断以保持较小的输出。如果有错误会显示出来。
然后我将其添加到app/AppKernel.php:
/**
* @see http://symfony.com/fr/doc/2.3/cookbook/configuration/override_dir_structure.html#surcharger-le-repertoire-cache
*/
public function getCacheDir()
{
$cachePath = getenv('CACHE_PATH');
if (
($this->environment == 'test')
&&
(! empty($cachePath))
) {
return(parent::getCacheDir().'/'.$cachePath.'/');
}
# else
return parent::getCacheDir();
}
这段代码将告诉 Symfony 在缓存文件夹中创建一个子目录,这意味着 PHPUnit 的多个实例不会使用相同的 SQLite 文件。
虽然它有效,但这个解决方案并不完美,并且有一些缺点:
- 即使我只想更改 SQLite 数据库的路径,它也会重新创建整个缓存
- 它将占用空间并花费时间为每个剩余文件创建一个缓存,如果您不将 RAM 用作缓存,我建议您避免这种情况(我的解决方案是删除cache并app/创建符号链接:
ln -s /run/shm/project/cache cache
,测试更快,因为缓存在 RAM 中完成,而不是在硬盘上)