alies-dev/psalm-tester
Run Psalm static analysis tests using .phpt fixtures. Define PHP code plus expected output (or EXPECTF), pass custom Psalm CLI args per tester or per test, and conditionally skip tests via SKIPIF. Integrates easily with PHPUnit test suites.
Batch Execution Support:
app/, packages/, tests/), enabling granular static analysis without overwhelming memory or CI/CD resources. This is particularly valuable for large monolithic applications or multi-package projects where full-codebase analysis is impractical.app/, tests/, and config/ into separate jobs can cut analysis time by 60–80% for large codebases.app/Http before expanding to app/Models), reducing risk and developer friction.Progress Output:
php artisan). This is critical for local debugging and CI feedback loops, where real-time progress clarifies bottlenecks.Conditional Analysis (--SKIPIF--):
local or testing (e.g., --SKIPIF-- env('APP_ENV') === 'local').hotfix/* or feature/* branches (e.g., --SKIPIF-- branch('hotfix')).@skipPsalm annotations or TestCase::skipPsalm()).APP_ENV, config(), and Artisan hooks for seamless integration (e.g., skip Psalm during php artisan migrate:fresh).Backward Compatibility:
Batch Execution:
app/ before tests/). Composer scripts (e.g., composer exec psalm-tester --batch="app/") simplify integration.psalm --stats --batch="group" to ensure no critical paths are missed. Example:
composer exec psalm-tester --batch="app/Http" --stats
php artisan psalm:batch --group="app/Models"), making it feel native to Laravel workflows.Progress Output:
--progress > psalm-progress.log) or suppressed in CI for clean logs. Example CI snippet:
- name: Run Psalm with Progress
run: composer exec psalm-tester --batch="app/" --progress | tee psalm.log
jq to extract metrics).Conditional Skipping (--SKIPIF--):
<psalm>
<fileList>
<directory name="app/" />
<skipIf condition="env('APP_ENV') === 'local' || branch() === 'hotfix'" />
</fileList>
</psalm>
@skipPsalm in Pest/PHPUnit) or when tests are excluded via --filter.Performance Trade-offs:
Batch Configuration Complexity:
app/Providers/).app/ first").psalm --list-errors --batch="group" to audit skipped sections.psalm --stats --batch="all".Progress Output Overhead:
grep -v "Progress").--quiet flag for CI and --progress for local development.Conditional Logic Pitfalls:
--SKIPIF-- rules may bypass critical checks.!hotfix/*).psalm --list-errors and enforce via PR reviews.config('psalm.skip_rules') to centralize conditions.Parallelization Race Conditions:
--init for incremental updates between batches.Batch Granularity Strategy:
app/, tests/), file type (.php, .blade.php), or Laravel-specific components (e.g., app/Providers/, app/Console/)?Progress Output Strategy:
psalm-progress.json) for CI artifacts?Conditional Skipping Scope:
--SKIPIF--?
local or testing, or for branches matching hotfix/* or !staging.@skipPsalm) override batch rules?CI Parallelization:
app/, tests/, config/ as separate jobs.Fallback Behavior:
Laravel-Specific Integration:
--SKIPIF-- leverage Laravel’s:
APP_ENV or custom config (e.g., config('psalm.enabled'))?migrate:fresh)?Documentation Needs:
--SKIPIF-- use cases for Laravel environments/branches?app/, packages/, and tests/ separately, reducing memory usage by ~40% for large codebases.--SKIPIF-- to dynamically skip Psalm in:
local or testing environments (e.g., --SKIPIF-- env('APP_ENV') === 'local').--SKIPIF-- branch() === 'hotfix').@skipPsalm annotated tests).jobs:
psalm-app:
run: composer exec psalm-tester --batch="app/"
psalm-tests:
run: composer exec psalm-tester --batch="tests/"
// app/Console/Commands/PsalmBatch.php
public function handle()
{
$groups = config('psalm.batch_groups', ['app/', 'tests/']);
foreach ($groups as $group) {
How can I help you explore Laravel packages today?