ezsystems/fastest

此包已被废弃且不再维护。作者建议使用liuggio/fastest包。

简单的并行测试执行...附带一些功能测试的实用工具。

v1.7.2 2020-03-17 13:30 UTC

README

Build Status Latest Stable Version Latest Unstable Version

唯一一件事

执行并行命令,为每个处理器创建一个进程(附带一些功能测试的实用工具)。

find tests/ -name "*Test.php" | ./vendor/liuggio/fastest/fastest "vendor/phpunit/phpunit/phpunit -c app {};"

Fastest 与任何可用的测试工具兼容!它只是并行执行。

它针对功能测试进行了优化,提供了在并行方式下轻松使用N个数据库的方法。

座右铭

"我遇到了一个问题,
所以决定使用线程。
tNwoowp rIo bhlaevmes。

为什么

我们厌倦了无法在我们的项目中(一个大型的复杂功能项目)运行 paratest
Parallel 是一个伟大的工具,但并不适合功能测试。
没有简单的工具可用于功能测试。

我们旧的代码库运行需要30分钟,现在只需要7分钟,使用4个处理器。

功能

  1. 功能测试可以使用环境变量为每个处理器使用一个数据库。
  2. 默认情况下,测试是随机化的。
  3. 它不与 PhpUnit 绑定,可以运行任何命令。
  4. 它使用 PHP 开发,没有依赖。
  5. 输入可以使用 phpunit.xml.dist 文件或使用管道(见下文)。
  6. 包含 Behat 扩展,可以轻松地将场景管道传输到 fastest。
  7. 使用 -v 选项增加详细程度。
  8. 可以在项目或全局模式下工作

如何

它创建 N 个线程,其中 N 是计算机核心的数量。
非常快,100% 使用 PHP 编写,受 Parallel 启发。

使用方法

配置二进制文件的路径

以下示例使用安装在 vendor/ 目录中的二进制文件的路径。您可以在 bin/ 目录中使用符号链接,通过定义 bin-dir 参数的 Composer

composer config "bin-dir" "bin"

然后您将能够在 bin/ 目录中调用二进制文件

  • bin/fastest 而不是 vendor/liuggio/fastest/fastest
  • bin/phpunit 而不是 vendor/phpunit/phpunit/phpunit

并行化一切

ls | ./fastest "echo slow operation on {}" -vvv

使用占位符

{} 是当前测试文件。
{p} 是当前处理器编号。
{n} 是当前测试的唯一编号。默认命令为 phpunit {}

PHPUnit

A. 使用 ls 列出文件夹作为输入 推荐

ls -d test/* | ./vendor/liuggio/fastest/fastest "vendor/phpunit/phpunit/phpunit {};"

B. 使用 find 列出 PHP 文件作为输入

find tests/ -name "*Test.php" | ./vendor/liuggio/fastest/fastest  "vendor/phpunit/phpunit/phpunit {};"

C. 使用 phpunit.xml.dist 作为输入

可以使用选项 -x 并从 phpunit.xml.dist 导入测试套件

./vendor/liuggio/fastest/fastest -x phpunit.xml.dist "vendor/phpunit/phpunit/phpunit {};"

如果使用此选项,请确保测试套件包含大量目录:此功能应改进,不要责怪帮助。

功能测试和数据库

在您的测试中,您可以使用环境变量。
如果您在一台有 4 个核心的计算机上运行测试,fastest 将创建 4 个并行线程,您可以在测试中这些变量来更好地识别当前进程。

echo getenv('ENV_TEST_CHANNEL');          // The number of the current channel that is using the current test eg.2
echo getenv('ENV_TEST_CHANNEL_READABLE'); // Name used to make the database name unique, is a readable name eg. test_2
echo getenv('ENV_TEST_CHANNELS_NUMBER');  // Max channel number on a system (the core number) eg. 4
echo getenv('ENV_TEST_ARGUMENT');         // The current running test eg. tests/UserFunctionalTest.php
echo getenv('ENV_TEST_INC_NUMBER');       // Unique number of the current test eg. 32
echo getenv('ENV_TEST_IS_FIRST_ON_CHANNEL'); // Is 1 if is the first test on its thread useful for clear cache.

before 中设置数据库

您还可以在每个进程 before 测试时运行一个脚本,这对于初始化模式和加载固定值很有用。

find tests/ -name "*Test.php" | ./vendor/liuggio/fastest/fastest -b"app/console doc:sch:create -e test" "vendor/phpunit/phpunit/phpunit {};";

生成和合并代码覆盖率

# Install phpcov in order to merge the code coverage
composer require --dev "phpunit/phpcov:~3.0"
# Create a directory where the coverage files will be put
mkdir -p cov/fastest/
# Generate as many files than tests, since {n} is an unique number for each test
find tests/ -name "*Test.php" | vendor/liuggio/fastest/fastest "vendor/phpunit/phpunit/phpunit -c app {} --coverage-php cov/fastest/{n}.cov;"
# Merge the code coverage files
phpcov merge cov/fastest/ --html cov/merge/fastest/

代码覆盖率将在 cov/merge/fastest/ 目录中可用。

存储适配器

如果您想并行执行功能测试,并且您有一台有 4 个 CPU 的机器,最好的做法是为每个并行进程创建一个数据库,fastest 让您轻松地与 Symfony 一起工作。

修改 Symfony 中的 config_test.yml 配置文件,每个功能测试将自动寻找一个名为 <database_name>_test_x 的数据库(x 是从 1 到 CPU 数量的数字)。

Doctrine DBAL

config_test.yml

parameters:
    # Stubs
    doctrine.dbal.connection_factory.class: Liuggio\Fastest\Doctrine\DBAL\ConnectionFactory

Doctrine MongoDB 连接

config_test.yml

parameters:
    # Stubs
    doctrine_mongodb.odm.connection.class: Liuggio\Fastest\Doctrine\MongoDB\Connection

SQLite 数据库

SQLite 数据库没有名称。总是每个文件一个数据库。如果检测到 SQLite 驱动程序,而不是切换数据库名称,将更改数据库路径。要使其正常工作,只需在数据库路径中添加 __DBNAME__ 占位符。

config_test.yml

doctrine:
    dbal:
        driver:   pdo_sqlite
        path:     "%kernel.cache_dir%/__DBNAME__.db"
        
parameters:
    doctrine.dbal.connection_factory.class: Liuggio\Fastest\Doctrine\DBAL\ConnectionFactory

其中 __DBNAME__ 将替换为 ENV_TEST_CHANNEL_READABLE 的值。

Behat.* 扩展

包含了一个 Behat 扩展,它提供了 Behat 能够输出一个列表的功能文件或将要执行的单个场景,而无需实际执行它们。此列表可以管道到 fastest 以并行运行场景。

要安装此扩展,只需将其添加到您的 behat.yml 文件中

extensions:
    Liuggio\Fastest\Behat\ListFeaturesExtension\Extension: ~

对于 Behat2

extensions:
    Liuggio\Fastest\Behat2\ListFeaturesExtension\Extension: ~

在此之后,您将有两个额外的命令行选项: --list-features--list-scenarios。前者将输出 *.feature 文件列表,后者将输出每个功能文件中的每个场景,包括其行号(例如:/full/path/Features/myfeature.feature:lineNumber)

这将允许您直接将输出管道化到最快,以便并行化其执行

/my/path/behat --list-scenarios | ./vendor/liuggio/fastest/fastest "/my/path/behat {}"

使用 --list-scenarios 比使用 --list-features 更好,因为它会提供更细粒度的场景输出,允许最快以更好的方式随机化和平衡单个测试。

关于基于浏览器的测试(Selenium、Mink等)

当浏览器通过PHPUnit、Behat或Fastest使用的其他测试套件远程控制时,浏览器会向服务器发送请求。问题是当服务器处理请求时,它不知道哪个最快通道调用了它,因此必须在连接到数据库之前设置此信息(以便选择与通道对应的正确数据库)。

一种可能的方法是实现以下步骤

1. 设置一个cookie、GET查询参数或HTTP头,带有适当的通道值

当您的测试场景开始时,可能在认证阶段,将以下之一设置为环境变量 ENV_TEST_CHANNEL_READABLE 的值

  • 如果是cookie或GET查询参数,请命名为 ENV_TEST_CHANNEL_READABLE
    • 请注意,如果您使用GET查询参数选项并通过自动化点击浏览器中不包含该查询参数的链接,则请求将不会包含查询参数,服务器将不知道要初始化的通道。
  • 如果是HTTP头,请命名为 X-FASTEST-ENV-TEST-CHANNEL-READABLE 并在每次向服务器发送请求时发送。

2. 配置应用程序的入口点以设置请求的环境变量

为此,只需在启动应用程序之前添加以下代码即可

\Liuggio\Fastest\Environment\FastestEnvironment::setFromRequest();

这将检测在#1中提到的任何上下文中ENV_TEST_CHANNEL_READABLE值的存在,并设置相应的环境变量。

例如,在Symfony框架的情况下,您可以在 web/app_dev.php 中添加它,就在 require_once __DIR__.'/../app/AppKernel.php' 之前。

// ... code
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
Debug::enable();

\Liuggio\Fastest\Environment\FastestEnvironment::setFromRequest();

require_once __DIR__.'/../app/AppKernel.php';
$kernel = new AppKernel('dev', true);
// ... code

安装

如果您使用Composer,只需运行 composer require --dev 'liuggio/fastest:^1.6'

或者简单地将liuggio/fastest依赖添加到项目的composer.json文件中

{
    "require-dev": {
	    "liuggio/fastest": "^1.6"
    }
}

通过Composer进行系统级安装,您可以运行

composer global require "liuggio/fastest=^1.6"

请确保 ~/.composer/vendor/bin/ 已添加到您的路径中,更多信息请参阅 getcomposer.org

如果您想与phpunit一起使用,您可能需要安装phpunit/phpunit作为依赖。

使用 fastest 运行此测试

简单 请参阅 .travis.yml 文件

参数

Usage:
 fastest [-p|--process="..."] [-b|--before="..."] [-x|--xml="..."] [-o|--preserve-order] [--no-errors-summary] [execute]

Arguments:
 execute               Optional command to execute.

Options:
 --process (-p)        Number of parallel processes, default: available CPUs.
 --before (-b)         Execute a process before consuming the queue, it executes this command once per process, useful for init schema and load fixtures.
 --xml (-x)            Read input from a phpunit xml file from the '<testsuites>' collection. Note: it is not used for consuming.
 --preserve-order (-o) Queue is randomized by default, with this option the queue is read preserving the order.
 --no-errors-summary   Do not display all errors after the test run. Useful with --vv because it already displays errors immediately after they happen.
 --help (-h)           Display this help message.
 --quiet (-q)          Do not output any message.
 --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
 --version (-V)        Display this application version.
 --ansi                Force ANSI output.
 --no-ansi             Disable ANSI output.
 --no-interaction (-n) Do not ask any interactive question.

已知问题

如果您遇到未知命令错误的问题,请确保您的 变量顺序 php.ini 设置包含 E。如果没有,则您的环境变量未设置,且在您的 PATH 中定义的命令将无法正常工作。

贡献

请帮助我们提供代码、爱、反馈和错误报告。

感谢

  • @giorrrgio 提供的 mongoDB 适配器
  • @diegosainz 提供的 Behat2 适配器
  • 你吗?

许可协议 License

阅读 LICENSE 了解更多信息。