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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity