turboparser/并行测试

PHP的并行测试

1.0.1 2017-07-02 12:52 UTC

README

Build Status Code Coverage Scrutinizer Code Quality Packagist

ParaTest的目标是支持PHPUnit的并行测试。只要你编写了良好的PHPUnit测试,你就可以将paratest添加到你的项目中,并开始使用,无需额外的引导或配置!

优点

为什么要在现有的替代并行测试运行程序中选用paratest

  • 代码覆盖率报告合并。在N个并行进程中运行测试,所有代码覆盖率输出将合并为一个报告。
  • 零配置。在composer安装后,运行vendor/bin/paratest -p4 path/to/tests。这就足够了!
  • 灵活。在单独的进程中隔离测试文件,或利用WrapperRunner实现更快的运行。

安装

Composer

要使用Composer安装,请运行以下命令

composer require --dev brianium/paratest

用法

安装后,二进制文件可在vendor/bin/paratest中找到。用法如下

Usage:
 paratest [-p|--processes="..."] [-f|--functional] [--no-test-tokens] [-h|--help] [--coverage-clover="..."] [--coverage-html="..."] [--coverage-php="..."] [-m|--max-batch-size="..."] [--filter="..."] [--phpunit="..."] [--runner="..."] [--bootstrap="..."] [-c|--configuration="..."] [-g|--group="..."] [--exclude-group="..."] [--stop-on-failure] [--log-junit="..."] [--colors] [--testsuite[="..."]] [--path="..."] [path]

Arguments:
 path                  The path to a directory or file containing tests. (default: current directory)

Options:
 --processes (-p)      The number of test processes to run. (default: 5)
 --functional (-f)     Run methods instead of suites in separate processes.
 --no-test-tokens      Disable TEST_TOKEN environment variables. (default: variable is set)
 --help (-h)           Display this help message.
 --coverage-clover     Generate code coverage report in Clover XML format.
 --coverage-html       Generate code coverage report in HTML format.
 --coverage-php        Serialize PHP_CodeCoverage object to file.
 --max-batch-size (-m) Max batch size (only for functional mode). (default: 0)
 --filter              Filter (only for functional mode).
 --phpunit             The PHPUnit binary to execute. (default: vendor/bin/phpunit)
 --runner              Runner or WrapperRunner. (default: Runner)
 --bootstrap           The bootstrap file to be used by PHPUnit.
 --configuration (-c)  The PHPUnit configuration file to use.
 --group (-g)          Only runs tests from the specified group(s).
 --exclude-group       Don't run tests from the specified group(s).
 --stop-on-failure     Don't start any more processes after a failure.
 --log-junit           Log test execution in JUnit XML format to file.
 --colors              Displays a colored bar as a test result.
 --testsuite           Filter which testsuite to run
 --path                An alias for the path argument.

优化速度

要充分利用paratest,你必须仔细调整参数。

  1. 使用-p调整进程数

    为了充分利用CPU核心,你应该至少有一个进程对应一个核心。更多的进程允许更好的资源利用,但请记住,每个进程都有自己的启动成本。

  2. 使用-f选项在单次测试用例-和单次测试方法-并行化之间选择

    如果你有一些测试用例(类)具有许多长时间运行的方法,你应该使用-f选项启用功能模式,允许同一类的不同方法并行执行。请注意,默认是按测试用例并行化,以解决测试方法之间的依赖关系。请注意,在大多数项目中,使用-f更慢,因为每个测试方法都需要单独引导。

  3. 如果可能的话,使用WrapperRunner

    PHPUnit的默认运行程序为每个测试用例(或功能模式中的方法)启动一个新的进程。这提供了最高的兼容性,但代价是许多启动的进程和每个进程的引导。特别是当你有缓慢的引导测试(如数据库设置)时,你应该尝试使用--runner WrapperRunner的WrapperRunner。它为每个并行进程(-p)启动一个“工作”进程,执行一次引导并重新使用这些进程来执行每个测试。这样,进程启动和引导的开销降至最低。

  4. 调整批处理最大大小--max-batch-size

    批量大小将影响单个测试方法中使用的原子测试的最大数量。如果没有为方法提供数据提供者,一个原子测试将是一个测试类中的一个测试方法,或者是一个方法的数据集中的单个项目。增加此值可以减少每个进程的开销,在大多数情况下,它也会降低并行效率。减少此值可以增加每个进程的开销,在大多数情况下,它也会提高并行效率。如果所有测试的数量小于最大批量大小,则所有内容将在一个进程线程中处理,所以在这种情况下,Paratest 完全无用。找到最有效的批量大小的方法是测试不同的批量大小值并选择最佳值。最大批量大小 = 0 表示不使用批量分组,一个批量将等于所有方法测试(来自数据提供者的一个或全部)。最大批量大小 = 1 表示每个批量将只包含来自数据提供者的一个测试或一个方法,如果未使用数据提供者。较大的最大批量大小可以显著增加 phpunit 命令行长度,因此进程可能会失败。减少最大批量大小以减少命令行长度。Windows 大约为 32k,Linux - 2048k,Mac OS X - 256k。

示例

以下示例假设您的测试位于 ./test/unit

# Run all unit tests in 8 parallel processes
vendor/bin/paratest -p8 test/unit
# Run all unit tests in 4 parallel processes with WrapperRunner and output html code coverage report to /tmp/coverage
# (Code coverage requires Xdebug to be installed)
vendor/bin/paratest -p8 --runner=WrapperRunner --coverage-html=/tmp/coverage test/unit

Windows

Windows 用户请务必使用适当的批处理文件。

例如:

vendor\bin\paratest.bat --phpunit vendor\bin\phpunit.bat ...

ParaTest 假设 PSR-0 用于加载测试。

为了方便起见,ParaTest Windows 版本使用 79 列模式,以防止在标准 80x25 Windows 控制台中出现空白行。

PHPUnit Xml 配置支持

当运行 PHPUnit 测试时,ParaTest 将自动通过 --configuration 开关将 phpunit.xml 或 phpunit.xml.dist 传递给 phpunit 运行器。ParaTest 还允许手动指定配置路径。

ParaTest 将依赖于 phpunit 的 xml 配置中的 testsuites 节来处理加载套件。

以下 phpunit 配置文件用于 ParaTest 的测试用例。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="../bootstrap.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
        >
    <testsuites>
        <testsuite name="ParaTest Fixtures">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
</phpunit>

测试令牌

TEST_TOKEN 环境变量保证具有一个与其他所有当前正在运行测试不同的值。这很有用,例如,为每个测试使用不同的数据库。

if (getenv('TEST_TOKEN') !== false) {  // Using paratest
    $dbname = 'testdb_' . getenv('TEST_TOKEN');
} else {
    $dbname = 'testdb';
}

对于贡献者:测试 paratest 本身

ParaTest 的测试套件依赖于通过 composer 安装的 PHPUnit。请确保在克隆后运行 composer install

注意:必须将 php.ini 中的 display_errors 指令设置为 stderr 以运行测试套件。

要运行单元测试:vendor/bin/phpunit test/unit

要运行功能测试:vendor/bin/phpunit test/functional

您可以通过在项目目录中运行 phpunit 来一次运行所有测试。vendor/bin/phpunit

ParaTest 可以通过从 bin 目录运行来运行其自己的测试套件。bin/paratest

在创建拉取请求之前,请务必运行 vendor/bin/php-cs-fixer fix 并提交最终更改。

要查看 ParaTest 的实际使用示例,请查看 示例