Skip to content

Run scenarios in parallel #390

Open
Open

Description

@schlessera

Scenarios run strictly one after another, even though almost all of them are independent and the CI runners have several cores. In a local experiment with 213 entity-command scenarios, a serial run took 491 seconds. With 8 workers it took 164 seconds when split by feature file, where one large file set the floor. Split by scenario, it took 140 seconds (3.5×).

Steps:

  1. Give each worker its own state: temporary directory, HOME, WP-CLI cache and test database. composer prepare-tests needs to grant access to the additional databases.
  2. Keep scenarios that rely on fixed shared resources, such as port 8080 or the scaffold test database, from running at the same time.
  3. Split the work by scenario rather than by file, balanced by the per-scenario timings from Measure Behat run times reliably #384.
  4. Merge the results into a single report and keep behat-rerun working.

Measuring: take the baseline from #384, then open a draft PR, run the same CI jobs against it with the parallel runner enabled and record both results here before we decide. CI runners have fewer cores than a development machine, so the gain there will be smaller than locally.

Activity

  1. schlessera commented on Oct 30, 2026

    @schlessera
    MemberAuthor

    Measurement

    Measured on GitHub Actions with the full test matrix of core-command and cache-command, run on measure/* branches of wp-cli/core-command#350 and wp-cli/cache-command#137. All runs use wp-cli-tests at the same base commit (9298472). The parallel run uses #405 with WP_CLI_TEST_PARALLEL=4, matching the 4 cores of the Linux runners.

    The metric is the Behat wall time of each job, from the start of the Behat step to its last summary, including any rerun of failed scenarios. "Total" is the sum over the Linux jobs present in all runs, "per job" the median of each job's change against the mean of the two baseline runs, which run identical code and show the noise level.

    core-command total core-command per job cache-command total cache-command per job
    Baseline A 6,970 s -9.9% 4,879 s -0.1%
    Baseline B 7,810 s +9.9% 4,950 s +0.1%
    #405, 4 workers 3,033 s -60.4% 2,507 s -51.5%

    The comparison covers 48 Linux jobs for cache-command and 29 for core-command, the ones whose logs could be read for all runs. Both ran the same scenarios as the baselines (1,138 and about 2,550 across these jobs).

    The run time of the Behat step roughly halves, and more than halves for core-command, whose scenarios are longer and balance better over the workers.

    Two things came up along the way:

    • features/core-download.feature:524 in core-command fails whenever it runs with an empty WP-CLI cache, also on its own in a serial run without any of these changes. A serial run of the whole suite only passes because the scenario before it puts the same download in the cache. In a parallel run, it fails in whichever worker it does not follow that scenario, as in the PHP 7.2 job above. That needs a fix in core-command (or wp core download --no-extract) before parallel runs can be enabled there.
    • A first measurement exposed that composer behat-rerun after a parallel run reran every scenario serially when WP_CLI_TEST_PARALLEL was not set for the rerun as well. Reruns now always cover exactly the failed scenarios. The other failed job is the Windows one, where Chocolatey timed out installing Ghostscript before any scenario ran.
  2. schlessera commented on Oct 31, 2026

    @schlessera
    MemberAuthor

    Measurement after wp-cli/core-command#355

    The core-download.feature:524 failure is fixed in wp-cli/core-command#355, which is merged. The core-command measurements were repeated on top of it, with fresh baselines and the same wp-cli-tests commit:

    core-command total core-command per job failed jobs
    Baseline A 9,116 s +1.9% 0
    Baseline B 8,385 s -1.9% 0
    #405, 4 workers 3,682 s -57.5% 0

    Every job of the matrix passes now, Windows and macOS included, and the parallel run executed the same 2,935 scenarios across the 33 Linux jobs compared here. The run time of the Behat step drops by about 58%, in line with the earlier measurement.

    For #391, the run in containers on the same base (3,131 s, -64.2%) still fails the 16 MySQL jobs, for the reasons described there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions