diff --git a/CHANGELOG.md b/CHANGELOG.md index c93f58d8..31223d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## Unreleased ### Added - Detect readiness state of new Selenium servers (v3.5.3+ running in W3C-protocol mode) during startup, so that eg. no available Selenium server nodes are reported before attempting to start any test. +- `--parallel-limit` (`-l`) option of `run` command to allow limiting maximum number of tests being run simultaneously. ### Changed - Require PHP 7.1+ and Symfony 4 components. diff --git a/README.md b/README.md index 75c1a189..18cef387 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ There is also a bunch of useful options for the `run` command: - `--server-url` - set different url of selenium server than the default (which is `http://localhost:4444/wd/hub`) - `--xdebug` - start Xdebug debugger on your tests. Allows you to debug tests from your IDE ([learn more about tests debugging][wiki-debugging] in our Wiki) - `--capability` - directly pass any extra capability to the Selenium WebDriver server ([see wiki][wiki-capabilities] for more information and examples) +- `--parallel-limit` - limit number of testcases being executed in a parallel (default is 50) - `--help` - see all other options and default values - **adjust output levels:** by default, only the test results summary is printed to the output; the verbosity could be changed by the following: - `-v` - to instantly output name of failed test(s) diff --git a/src-tests/Console/Command/Fixtures/FailingTests/expected-very-verbose-output.txt b/src-tests/Console/Command/Fixtures/FailingTests/expected-very-verbose-output.txt index 6a86185c..016d2d98 100644 --- a/src-tests/Console/Command/Fixtures/FailingTests/expected-very-verbose-output.txt +++ b/src-tests/Console/Command/Fixtures/FailingTests/expected-very-verbose-output.txt @@ -3,6 +3,7 @@ Browser: chrome Environment: staging Path to logs: %s/logs Ignore delays: no +Parallel limit: 50 Selenium server (hub) url: %s, trying connection...OK Searching for testcases: - in directory %s/src-tests/Console/Command/Fixtures/FailingTests" diff --git a/src-tests/Console/Command/Fixtures/SimpleTests/expected-debug-output.txt b/src-tests/Console/Command/Fixtures/SimpleTests/expected-debug-output.txt index b81533c4..3d92474c 100644 --- a/src-tests/Console/Command/Fixtures/SimpleTests/expected-debug-output.txt +++ b/src-tests/Console/Command/Fixtures/SimpleTests/expected-debug-output.txt @@ -3,6 +3,7 @@ Browser: chrome Environment: staging Path to logs: %s/logs Ignore delays: no +Parallel limit: 50 Selenium server (hub) url: %s, trying connection...OK Searching for testcases: - in directory "%s/src-tests/Console/Command/Fixtures/SimpleTests" diff --git a/src-tests/Console/Command/Fixtures/SimpleTests/expected-very-verbose-output.txt b/src-tests/Console/Command/Fixtures/SimpleTests/expected-very-verbose-output.txt index 5d059aff..f984c5e2 100644 --- a/src-tests/Console/Command/Fixtures/SimpleTests/expected-very-verbose-output.txt +++ b/src-tests/Console/Command/Fixtures/SimpleTests/expected-very-verbose-output.txt @@ -3,6 +3,7 @@ Browser: chrome Environment: staging Path to logs: %s/logs Ignore delays: no +Parallel limit: 50 Selenium server (hub) url: %s, trying connection...OK Searching for testcases: - in directory "%s/src-tests/Console/Command/Fixtures/SimpleTests" diff --git a/src/Console/Command/RunCommand.php b/src/Console/Command/RunCommand.php index 8cc93b52..d20235f6 100644 --- a/src/Console/Command/RunCommand.php +++ b/src/Console/Command/RunCommand.php @@ -51,6 +51,7 @@ class RunCommand extends Command public const OPTION_FILTER = 'filter'; public const OPTION_NO_EXIT = 'no-exit'; public const OPTION_IGNORE_DELAYS = 'ignore-delays'; + public const OPTION_PARALLEL_LIMIT = 'parallel-limit'; /** * @internal @@ -148,6 +149,13 @@ protected function configure(): void 'i', InputOption::VALUE_NONE, 'Ignore delays defined between testcases' + ) + ->addOption( + self::OPTION_PARALLEL_LIMIT, + 'l', + InputOption::VALUE_REQUIRED, + 'Number of maximum testcases being executed in a parallel', + 50 ); $this->addUsage('staging firefox'); @@ -204,6 +212,13 @@ protected function initialize(InputInterface $input, OutputInterface $output): v $seleniumAdapter = $this->getSeleniumAdapter($input->getOption(self::OPTION_SERVER_URL)); $input->setOption(self::OPTION_SERVER_URL, $seleniumAdapter->getServerUrl()); + // Make sure parallel-limit is greater than 0 + $parallelLimit = (int) $input->getOption(self::OPTION_PARALLEL_LIMIT); + if ($parallelLimit === 0) { + throw new \RuntimeException('Parallel limit must be a whole number greater than 0'); + } + $input->setOption(self::OPTION_PARALLEL_LIMIT, $parallelLimit); + $this->getDispatcher()->dispatch( CommandEvents::RUN_TESTS_INIT, new ExtendedConsoleEvent($this, $input, $output) @@ -216,6 +231,9 @@ protected function initialize(InputInterface $input, OutputInterface $output): v $output->writeln( sprintf('Ignore delays: %s', ($input->getOption(self::OPTION_IGNORE_DELAYS)) ? 'yes' : 'no') ); + $output->writeln( + sprintf('Parallel limit: %d', $input->getOption(self::OPTION_PARALLEL_LIMIT)) + ); } } @@ -263,7 +281,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 1; } - $executionLoop = new ExecutionLoop($processSet, $this->io, new MaxTotalDelayStrategy()); + $maxParallelLimit = $input->getOption(self::OPTION_PARALLEL_LIMIT); + + $executionLoop = new ExecutionLoop($processSet, $this->io, new MaxTotalDelayStrategy(), $maxParallelLimit); $allTestsPassed = $executionLoop->start();