irl / paratest
PHP 的并行测试 | 为 IRL 实现而分支
Requires
- php: ^7.3
- ext-dom: *
- ext-json: *
- ext-pcre: *
- ext-pdo: *
- ext-reflection: *
- ext-simplexml: *
- brianium/habitat: 1.0.0
- phpunit/php-code-coverage: ^8.0
- phpunit/php-timer: ^5.0
- phpunit/phpunit: ^9.2
- symfony/console: ^3.4 || ^4.0 || ^5.0
- symfony/process: ^3.4 || ^4.0 || ^5.0
Requires (Dev)
- phpstan/phpstan: ^0.12.33
- phpstan/phpstan-phpunit: ^0.12.12
- squizlabs/php_codesniffer: ^3.5
This package is not auto-updated.
Last update: 2024-09-27 08:58:38 UTC
README
ParaTest 的目标是支持 PHPUnit 的并行测试。只要你编写了良好的 PHPUnit 测试,你就可以在你的项目中添加 paratest 并开始使用,无需额外的引导或配置!
优点
为什么要在现有的并行测试运行程序中选择 paratest 而不是其他选择呢?
- 代码覆盖率报告合并。 在 N 个并行进程中运行测试,所有的代码覆盖率输出将合并成一个报告。
- 零配置。 安装 composer 后,运行
vendor/bin/paratest -p4 path/to/tests。就这样! - 灵活。 在单独的进程中隔离测试文件,或者利用 WrapperRunner 实现更快地运行。
安装
使用 composer 安装,请运行以下命令
composer require --dev brianium/paratest
版本
用法
安装后,二进制文件可以在 vendor/bin/paratest 下找到。用法如下
Usage:
paratest [-p|--processes PROCESSES] [-f|--functional] [--no-test-tokens] [-h|--help] [--coverage-clover COVERAGE-CLOVER] [--coverage-crap4j COVERAGE-CRAP4J] [--coverage-html COVERAGE-HTML] [--coverage-php COVERAGE-PHP] [--coverage-text] [--coverage-xml COVERAGE-XML] [-m|--max-batch-size MAX-BATCH-SIZE] [--filter FILTER] [--parallel-suite] [--passthru PASSTHRU] [--passthru-php PASSTHRU-PHP] [-v|--verbose VERBOSE] [--whitelist WHITELIST] [--phpunit PHPUNIT] [--runner RUNNER] [--bootstrap BOOTSTRAP] [-c|--configuration CONFIGURATION] [-g|--group GROUP] [--exclude-group EXCLUDE-GROUP] [--stop-on-failure] [--log-junit LOG-JUNIT] [--colors] [--testsuite [TESTSUITE]] [--path 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: auto)
Possible values:
- Integer (>= 1): Number of processes to run.
- auto (default): Number of processes is automatically set to the number of logical CPU cores.
- half: Number of processes is automatically set to half the number of logical CPU cores.
--functional (-f) Run test methods instead of classes 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-crap4j Generate code coverage report in Crap4J XML format.
--coverage-html Generate code coverage report in HTML format.
--coverage-php Serialize PHP_CodeCoverage object to file.
--coverage-text Generate code coverage report in text format.
--coverage-xml Generate code coverage report in PHPUnit XML format.
--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, WrapperRunner or SqliteRunner. (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. Run multiple suits by separating them with ",". Example: --testsuite suite1,suite2
--path An alias for the path argument.
--parallel-suite Run testsuites in parallel as opposed to running test classes / test functions in parallel.
--passthru=PASSTHRU Pass the given arguments verbatim to the underlying test framework. Example: --passthru="'--prepend' 'xdebug-filter.php'"
--passthru-php=PASSTHRU-PHP Pass the given arguments verbatim to the underlying php process. Example: --passthru-php="'-d' 'zend_extension=xdebug.so'"
-v, --verbose=VERBOSE If given, debug output is printed. Example: --verbose=1
优化速度
要充分发挥 paratest 的作用,你必须仔细调整参数。
-
使用
-p调整进程数量为了充分利用你的 CPU 核心,你应该至少有一个进程对应一个核心。更多的进程允许更好的资源利用,但请注意,每个进程都有自己的启动成本。默认值为自动,这意味着逻辑 CPU 核心的数量被设置为进程数量。你可能尝试像逻辑
CPU 核心数 * 2(例如,如果你有 8 个逻辑核心,你可能尝试16),但请注意,每个进程都会产生一点开销。 -
使用
-f选择按测试用例或按测试方法并行化如果你有很少的测试用例(类)但有多个运行时间长的测试方法,你应该使用
-f选项来启用功能模式并允许同一类的不同方法并行执行。请注意,默认值为按测试用例并行化,以解决测试方法之间的依赖关系。请注意,在大多数项目中,使用-f是 更慢的,因为每个测试 方法 都需要单独引导。 -
如果可能的话,使用 WrapperRunner 或 SqliteRunner
PHPUnit 默认的 Runner 为每个测试用例(或功能模式中的方法)启动一个新的进程。这提供了最高的兼容性,但伴随着许多启动进程和每个进程的引导成本。特别是当你有缓慢的引导(如数据库设置)时,你应该尝试使用
--runner WrapperRunner的 WrapperRunner 或使用--runner SqliteRunner的 SqliteRunner。它为每个并行进程(-p)启动一个“工作”进程,执行一次引导并重复使用这些进程执行每个测试。这样,进程启动和引导的开销就降到最低。 -
调整批处理最大大小
--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 -p4 --runner=WrapperRunner --coverage-html=/tmp/coverage test/unit
故障排除
如果您遇到与 paratest 相关的问题,请通过启用调试输出(--verbose=1)来尝试获取有关问题的更多信息。
如果您使用的是 WrapperRunner 进行执行,请考虑通过 export PT_LOGGING_ENABLE="true" 启用日志记录以进行故障排除。相应的日志文件位于您的 sys_get_temp_dir()。
有关更多信息,请参阅 日志记录文档。
生成代码覆盖率
示例假设您的测试位于 ./test/unit 下。
vendor/bin/paratest -p 1 --coverage-text test/unit
Running phpunit in 1 process with /codebase/paratest/vendor/phpunit/phpunit/phpunit
Configuration read from /codebase/paratest/phpunit.xml.dist
............................................................... 63 / 155 ( 40%)
............................................................... 126 / 157 ( 80%)
.....................................
Time: 27.2 seconds, Memory: 8.00MB
OK (163 tests, 328 assertions)
Code Coverage Report:
2019-01-25 09:41:26
Summary:
Classes: 22.86% (8/35)
Methods: 49.47% (139/281)
Lines: 59.38% (896/1509)
注意:生成覆盖率本身就是一个艺术。请参阅我们关于如何正确设置 paratest 生成代码覆盖率 的全面指南。
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 才能运行测试套件。
您可以使用 composer 脚本来方便地访问代码风格检查和测试。运行 compose run-script -l 以列出可用的命令。
composer run-script -l
scripts:
style Run style checks (only dry run - no fixing!)
style-fix Run style checks and fix violations
static-analysis Run static analysis
test Run all tests
test-unit Run only unit tests
test-functional Run only functional tests
test-paratest Run all tests with paratest itself
运行单元测试:composer test-unit 或 vendor/bin/phpunit test/unit
运行功能测试:composer test-functional 或 vendor/bin/phpunit test/functional
您可以通过在项目目录中运行 phpunit 来一次性运行所有测试:composer test 或 vendor/bin/phpunit
ParaTest 可以通过从 bin 目录运行来运行其自身的测试套件:composer test 或 bin/paratest
静态分析代码:composer static-analysis
在创建Pull Request之前,请务必运行样式检查并提交最终更改: composer style-fix
使用composer style仅显示违规而不会进行修复。
要查看ParaTest的实际应用示例,请查看示例。