July 6th 2026 open source test splitter
Test Splitter is a small open source tool that splits a PHPUnit test suite into batches, in a deterministic way. Each batch can then be run in a separate CI job. If your test suite takes 20 minutes to run, splitting it over 4 parallel jobs gets feedback to the team in roughly 5 minutes.
I built it in 2021 to solve a problem on a couple of client projects: test suites that had grown to the point where the feedback loop was painfully slow, on CI platforms that made it easy to run jobs in parallel but offered no way to divide the tests between them.
Install it with composer:
composer require --dev dave-liddament/test-splitter
The package provides a single executable, vendor/bin/tsplit, which takes two arguments: the batch number and the total number of batches.
It reads a list of tests from stdin and writes the tests belonging to the requested batch to stdout.
Combine it with PHPUnit's --list-tests and --filter options to run just one batch of tests.
For example, to split the suite into 4 batches and run the first one:
vendor/bin/phpunit --filter `vendor/bin/phpunit --list-tests | vendor/bin/tsplit 1 4`
Because the split is deterministic, every job that asks for batch 1 of 4 gets the same tests, and the batches never overlap or miss a test.
The tool really pays off in CI pipelines. With GitHub Actions, use a matrix to run each batch as its own job:
jobs:
tests:
strategy:
fail-fast: false
matrix:
test-batch: [1, 2, 3, 4]
steps:
# Steps to checkout code, setup environment, etc.
- name: "Tests batch ${{ matrix.test-batch }}"
run: vendor/bin/phpunit --filter `vendor/bin/phpunit --list-tests | vendor/bin/tsplit ${{ matrix.test-batch }} 4`
GitLab CI/CD makes it even simpler. Its predefined variables CI_NODE_INDEX and CI_NODE_TOTAL supply the batch numbers automatically:
test:
stage: test
parallel: 4
script:
- vendor/bin/phpunit --filter `vendor/bin/phpunit --list-tests | vendor/bin/tsplit ${CI_NODE_INDEX} ${CI_NODE_TOTAL}`
Test Splitter is deliberately a very simple tool. When it was created in 2021 nothing else did the job; that's no longer true. If you want something more feature rich, look at Paratest (with its shard functionality) or Shipmonk's PHPUnit parallel job balancer. That said, if all you need is to split a PHPUnit suite over a few parallel CI jobs, Test Splitter does exactly that — and nothing else.