Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Psalm Tester Laravel Package

phpyh/psalm-tester

Run Psalm assertions from .phpt files. Write phpt tests with --FILE-- and --EXPECT/EXPECTF-- for traces and errors, then execute them via a PHPUnit test suite using PsalmTester. Supports per-suite default Psalm args and per-test --ARGS-- overrides.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require --dev phpyh/psalm-tester
    

    Ensure psalm is installed globally or via Composer (composer require --dev vimeo/psalm).

  2. Basic Configuration Add to composer.json under extra:

    "psalm": {
        "bin": "vendor/bin/psalm",
        "config": "psalm.xml"
    }
    

    Or configure via PsalmTester::setPsalmConfig() in PHP.

  3. First Use Case Run a simple test to verify Psalm’s output:

    use Phyh\PsalmTester\PsalmTester;
    
    test('Psalm passes with no errors', function () {
        $result = PsalmTester::run();
        $result->assertNoErrors();
    });
    

Key Files to Review

  • tests/PsalmTest.php (if creating custom assertions)
  • config/psalm.xml (Psalm’s core config)
  • phpunit.xml (if integrating with PHPUnit)

Implementation Patterns

Workflows

1. CI Integration

Use in GitHub Actions/GitLab CI to enforce Psalm compliance:

# .github/workflows/psalm.yml
jobs:
  psalm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: composer install
      - run: vendor/bin/phpunit --testdox-html --filter "Psalm"

2. Test-Driven Static Analysis

Assert expected errors for new/changed code:

test('New method triggers expected Psalm error', function () {
    $result = PsalmTester::run(['--init']);
    $result->assertErrorContains('ClassMyClass has a method with no return type');
});

3. Baseline Validation

Compare against a snapshot of "known good" output:

test('Psalm output matches baseline', function () {
    $result = PsalmTester::run();
    $result->assertOutputMatchesFile(__DIR__.'/baseline.txt');
});

4. Laravel-Specific Patterns

  • Service Provider Bootstrapping:
    PsalmTester::setPsalmConfig(app()->basePath('psalm.xml'));
    
  • Artisan Command Integration:
    use Illuminate\Console\Command;
    use Phyh\PsalmTester\PsalmTester;
    
    class RunPsalmCommand extends Command {
        protected $signature = 'psalm:run';
        public function handle() {
            $result = PsalmTester::run();
            $this->line($result->getOutput());
            if ($result->hasErrors()) {
                $this->error('Psalm found issues!');
            }
        }
    }
    

Integration Tips

  • Combine with pest or phpunit: Use PsalmTester in feature tests to validate type safety.
  • Parallelize Tests: Run Psalm on subsets of files in CI for speed:
    PsalmTester::run(['--threads', '--init', 'src/']);
    
  • Custom Assertions: Extend PsalmTesterResult for project-specific checks:
    $result->assertErrorCount(3); // Custom assertion
    

Gotchas and Tips

Pitfalls

  1. False Positives in CI

    • Issue: Psalm output varies across environments (e.g., vendor/ paths).
    • Fix: Use --init to regenerate cache or mock vendor/ in tests:
      PsalmTester::run(['--init', '--no-cache']);
      
  2. Slow Test Suites

    • Issue: Full Psalm runs block test parallelization.
    • Fix: Run Psalm separately in CI or use --threads:
      vendor/bin/psalm --threads=4 --init
      
  3. Baseline Drift

    • Issue: Manual baseline updates become tedious.
    • Fix: Use a script to auto-generate baselines:
      vendor/bin/psalm --init > baseline.txt
      
  4. Laravel-Specific Quirks

    • Issue: Psalm misinterprets Laravel’s dynamic properties (e.g., Illuminate\Support\Collection).
    • Fix: Configure Psalm’s ignoreErrors in psalm.xml:
      <error-level>Errors</error-level>
      <ignoreErrors>
          <error>MixedAssignment</error>
          <error>MixedReturnType</error>
      </ignoreErrors>
      

Debugging

  • Verbose Output: Enable Psalm’s debug mode:
    PsalmTester::run(['--debug']);
    
  • Dry Runs: Test without modifying files:
    PsalmTester::run(['--no-cache', '--init']);
    
  • Isolate Errors: Run Psalm on a single file:
    PsalmTester::run(['src/MyClass.php']);
    

Extension Points

  1. Custom Error Parsing Override PsalmTesterResult::parseOutput() to handle project-specific Psalm formats.

  2. Pre/Post-Run Hooks Extend PsalmTester to run setup/teardown:

    PsalmTester::beforeRun(function () {
        // Copy config files, etc.
    });
    
  3. Git Pre-Commit Hooks Use PsalmTester to block commits with Psalm errors:

    # .git/hooks/pre-commit
    vendor/bin/phpunit --filter "Psalm" || exit 1
    
  4. Visual Studio Code Integration Add a task to run Psalm via PsalmTester in tasks.json:

    {
      "label": "Run Psalm",
      "type": "process",
      "command": "vendor/bin/phpunit --filter Psalm",
      "problemMatcher": ["$phpunit"]
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle