Testing
Pyle provides one complete test command and smaller scopes for focused local development. The same runner powers local development and CI, so a failing CI lane can be reproduced without reconstructing its Pest command by hand.
Running the Complete Suite
From the repository root, run:
composer testThe complete suite runs:
- root PHPStan analysis;
- Framework PHP tests;
- Admin, Storefront, Admin Panel host, and host Feature PHP tests;
- both ERP Bridge test roots;
- Admin Panel Vitest tests and package typechecking;
- host application typechecking, production builds, and SSR builds; and
- test inventory and workflow contract guards.
Every intended PHP suite uses Pest's empty-suite failure guard. CI also checks that each registered test root contributes tests to its JUnit report, which prevents a configuration or discovery change from silently dropping coverage.
Installing Dependencies
The complete suite needs the root, Framework, and embedded Laravel application Composer dependencies. It also needs the Admin Panel package and embedded application npm dependencies:
composer install
composer install --working-dir=packages/framework
composer install --working-dir=apps/laravel
npm ci --prefix packages/admin-panel
npm ci --prefix apps/laravelYou may install only the dependencies needed by the scope you are working on. The runner reports missing dependency directories before starting a suite.
Pyle's current dependency locks require PHP 8.4. If PHP 8.4 is not the first PHP executable on your PATH, set PYLE_PHP_BINARY:
PYLE_PHP_BINARY="$HOME/Library/Application Support/Herd/bin/php84" composer test:appRunning a Focused Scope
Use the smallest scope that exercises your change while iterating:
composer test:framework
composer test:app
composer test:erp
composer test:frontend
composer test:contractstest:app includes Admin, Storefront, Admin Panel host, and host Feature PHP tests. test:frontend runs the Admin Panel Vitest suite and package typecheck, then generates the host Admin Panel assets and runs the host typecheck, production build, and SSR build. test:contracts verifies the test inventory and the GitHub Actions workflow contract tests.
Pass Pest arguments after a second --. Runner arguments, such as the process count, belong before it:
composer test:app -- --processes=4 -- --filter=OrdersIndexControlling Parallelism
PHP suites use up to eight workers by default. This is the best local wall-time-to-compute compromise measured for the complete suite. Override the worker count with either the environment or a runner option:
PYLE_TEST_PROCESSES=4 composer test:app
composer test:app -- --processes=4Run serially when diagnosing isolation or order-dependent behavior:
composer test:framework -- --serialNative Windows shells use serial execution because Pest parallel execution is not reliable there. Use WSL to run the suites in parallel on Windows.
Reproducing CI Shards
CI splits the Framework suite into two measured, time-balanced lanes on 8-vCPU runners. Reproduce either lane locally with:
composer test:framework -- --shard=1/2
composer test:framework -- --shard=2/2Pest owns the committed tests/.pest/shards.json timing manifest. Refresh it after adding, deleting, or renaming Framework test files or classes, or after a test's runtime changes materially:
node .github/scripts/run-test-suite.mjs framework --ci -- --update-shardsDo not combine --shard with --processes. Pest sizes shard and manifest discovery runs from the CPUs available to the process.
Understanding the PHP Layers
Framework tests are classified by their actual runtime requirements rather than their directory name:
PureUnitruns without Laravel;Applicationboots Laravel without refreshing a database; and- database-backed Unit, Feature, and ERP tests retain the full schema and transactional isolation contract.
The Framework scope excludes the erp-bridge group. The ERP scope owns that group and verifies that its discovery exactly matches both intended ERP test roots before executing it.
Running API Contract Checks
API documentation artifacts are generated from the embedded Laravel application. Install its dependencies, then generate or verify the artifacts:
cd apps/laravel
npm run api-docs:generate
npm run api-docs:verifyGeneration uses an in-memory SQLite connection and does not migrate an application database. See the API contract guide for artifact ownership and CI behavior.