Run the test suite
$ grim test --filter=CartTest
Before a commit, after moving to a new train, while chasing one failing test. grim test is the way to run the suite, and it is more than a shortcut for artisan test: it makes sure the tests run against their own database and not the one you develop on, and it switches off the drivers that would let a test send mail or queue a job for real.
grim release runs this same sequence before it builds anything, so a suite that passes here passes there.
Usage
$ grim test # the whole suite
$ grim test --filter=CartTest # one class or method
$ grim test tests/Feature # one directory
$ grim test --stop-on-failure # any artisan test optionRun it from the project directory, with the stack up. Everything after test is handed to artisan test exactly as typed; no double dash is needed.
Arguments and options
Run tests in app container
Usage
grim test [<args>...]Arguments
| Argument | Description |
|---|---|
args |
Test arguments (e.g., --filter=CartTest) (optional, repeatable) |
What it actually does
- Names the test database. The project name from
grim.jsonwith_testadded:shop_test. - Creates it when it does not exist. The host, port, user and password are read from the project's
.env, so it lands on the same database server your app uses. The statement isCREATE DATABASE IF NOT EXISTS, inutf8mb4. - Migrates it.
php artisan migrate --forceagainst the test database, on every run. New migrations are applied before the first test starts. - Runs
php artisan testin the app container with your arguments and your terminal attached. The exit code is the suite's.
For the run, and only for the run, these values replace what .env says.
| Variable | Value | So that |
|---|---|---|
APP_ENV |
testing |
The app knows it is under test. |
DB_DATABASE |
shop_test |
Your development data is never touched. |
SESSION_DRIVER, CACHE_DRIVER |
array |
Nothing leaks between tests or into Redis. |
QUEUE_CONNECTION |
sync |
Jobs run inline, where a test can see them. |
MAIL_MAILER |
array |
No mail leaves the process. |
They are passed to the container directly because the values Docker Compose injects from .env would otherwise win over the ones in phpunit.xml.
Pitfalls
A failed database setup does not stop the run
⚠ Test database setup failed — tests may fail with "Unknown database". is followed by what MySQL or the migration said, and then the suite starts anyway. Read that output first: a wall of red tests below it has one cause. The usual ones are a database server that is not running and a user in .env that may not create databases.
The test database is never emptied by grim
It is created and migrated, not reset. Rows survive between runs unless the tests clean up, for instance with Laravel's RefreshDatabase. When it is past saving, drop shop_test by hand and the next run builds it again.
The stack has to be up
Both the setup and the suite enter the running app container. service "app" is not running means grim up comes first.
After it finishes
A green run means the code is ready to commit. A red one names the failing tests; run one of them alone while you work on it.
$ grim test --filter=test_cart_total_includes_vatRelated spells
grim artisan
Run artisan in the container
Run an artisan command inside the app container, where the app's PHP, extensions and environment are.
grim up
Raise the stack
Start the project's containers and its Vite dev server, with a trusted certificate and a working address, and say where to open it.
grim update
Board the newest train
Move core, every module and every theme onto the newest release train grim.json allows, or a single module within the train it is on.
grim release
Ship in one pass
Test, build, push and deploy the project to an environment with a single command and a single tag.
grim logs
Read the logs
Show what the containers have been printing, for one service or all of them, on your machine or on a deployed server.