Skip to content

Running the test suite ​

The test suite runs on an in-memory SQLite database by default:

bash
composer test

To run it against MySQL or PostgreSQL, start the databases from compose.yml and point the suite at them:

bash
docker compose up -d mysql pgsql
DB_CONNECTION=mysql DB_PORT=33306 composer test
DB_CONNECTION=pgsql DB_PORT=54329 composer test

Database name, user and password default to query_builder, user and secret, which matches compose.yml. Override them with DB_DATABASE, DB_USERNAME, DB_PASSWORD and DB_HOST when needed.

On MySQL and PostgreSQL the fixture schema and data are built once per test process, and every test runs in a transaction that is rolled back afterwards (the ported spatie suite in tests/Compat still migrates its own tables for each test). A sequential run uses one database, so do not start two runs against the same server at once.

The suite also runs in parallel, one process per CPU core by default:

bash
composer test:parallel
DB_CONNECTION=mysql DB_PORT=33306 composer test:parallel
DB_CONNECTION=pgsql DB_PORT=54329 composer test:parallel
vendor/bin/pest --parallel --processes=4

Each process gets a database of its own, <DB_DATABASE>_<n> (query_builder_1, query_builder_2, …), created on first use and kept for the next run. The database user therefore needs the right to create these databases:

  • PostgreSQL: the user of compose.yml is a superuser, nothing to do.

  • MySQL: compose.yml grants user all privileges on query\_builder\_% through docker/mysql-init.sql, which runs only when the data volume is created. For a container created before that script existed, grant them once by hand:

    bash
    docker compose exec mysql mysql -uroot -psecret \
        -e "GRANT ALL PRIVILEGES ON \`query\\_builder\\_%\`.* TO 'user'@'%'"

    or recreate the container with its data: docker compose rm -sfv mysql, then docker compose up -d mysql.

The whole suite can also run inside Docker, without PHP on the host:

bash
docker compose build php
docker compose run --rm php composer install
docker compose run --rm php composer test
docker compose up -d mysql pgsql
docker compose run --rm -e DB_CONNECTION=mysql -e DB_HOST=mysql -e DB_PORT=3306 php composer test
docker compose run --rm -e DB_CONNECTION=pgsql -e DB_HOST=pgsql -e DB_PORT=5432 php composer test

Build the image with another PHP version:

bash
PHP_VERSION=8.3 docker compose build php

On a Linux host whose user id is not 1000, build with your own id so files written to the bind mount keep the right owner:

bash
docker compose build --build-arg UID="$(id -u)" php

Static analysis and code style:

bash
composer analyse
composer lint