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

Phpunit Testlistener Vcr Laravel Package

covergenius/phpunit-testlistener-vcr

PHPUnit test listener that records and replays HTTP interactions using a VCR-style approach. Capture real API responses into cassettes during tests, then replay them for fast, deterministic runs without hitting external services.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require --dev covergenius/phpunit-testlistener-vcr
    

    Add the listener to your phpunit.xml:

    <listeners>
        <listener class="Covergenius\TestListenerVcr\VcrListener" file="./vendor/covergenius/phpunit-testlistener-vcr/src/VcrListener.php" />
    </listeners>
    
  2. Configure PHP-VCR Ensure php-vcr is installed (php-vcr/php-vcr) and configured in your project. The listener relies on its cassettes.

  3. First Use Case Run tests with VCR recording enabled:

    ./vendor/bin/phpunit --vcr-record=once
    

    This records HTTP interactions for the first run and replays them in subsequent runs.


Implementation Patterns

Workflow Integration

  1. Test Execution Lifecycle

    • Record Mode: Use --vcr-record=once or --vcr-record=all to capture HTTP calls for new tests.
    • Replay Mode: Default behavior replays cassettes, skipping external requests (faster tests).
    • Update Mode: Use --vcr-record=update to overwrite existing cassettes (e.g., after API changes).
  2. Conditional Recording Leverage PHP-VCR’s shouldIntercept() to exclude specific tests or endpoints:

    public function testExternalApi() {
        $this->markTestSkipped('Skip VCR for this test');
        // OR
        VCR::shouldIntercept(function () {
            return false; // Disable VCR for this test
        });
    }
    
  3. CI/CD Pipeline

    • Record in Dev: Developers record cassettes locally (--vcr-record=once).
    • Replay in CI: Run tests in CI without recording (--vcr-record=none) for deterministic builds.
    • Update on Merge: Use --vcr-record=update in a post-merge job to sync cassettes.
  4. Test Isolation Use unique cassette paths per test class or method to avoid conflicts:

    <listeners>
        <listener class="Covergenius\TestListenerVcr\VcrListener">
            <arguments>
                <argument value="tests/_cassettes/%classname%/%methodname%.yaml" type="string"/>
            </arguments>
        </listener>
    </listeners>
    

Gotchas and Tips

Pitfalls

  1. Cassette Mismatches

    • Symptom: Tests fail with VCR::Error\PlaybackException due to mismatched HTTP responses.
    • Fix: Update cassettes with --vcr-record=update or manually edit YAML files. Use php-vcr's VCR::shouldIntercept() to debug specific tests.
  2. Environment-Specific Responses

    • Issue: Cassettes recorded in dev may fail in staging due to different API responses (e.g., headers, timestamps).
    • Solution: Use environment-specific cassette paths or normalize responses in VCR::beforeRecord():
      VCR::beforeRecord(function ($interaction) {
          $interaction->response->headers->remove('date');
      });
      
  3. Listener Initialization Order

    • Problem: The listener may not load if PHPUnit’s autoloader isn’t configured correctly.
    • Fix: Ensure the listener class is fully qualified (e.g., Covergenius\TestListenerVcr\VcrListener) and the file attribute in phpunit.xml points to the correct path.
  4. Dynamic API Endpoints

    • Challenge: Tests with dynamic URLs (e.g., /api/v1/users/{id}) may fail replay.
    • Workaround: Use VCR::beforeRecord() to rewrite URLs:
      VCR::beforeRecord(function ($interaction) {
          $interaction->request->uri = str_replace('/api/v1/users/123', '/api/v1/users/{id}', $interaction->request->uri);
      });
      

Debugging Tips

  1. Verbose Logging Enable debug output to inspect VCR interactions:

    ./vendor/bin/phpunit --vcr-log-level=debug
    

    Or configure in phpunit.xml:

    <listeners>
        <listener class="Covergenius\TestListenerVcr\VcrListener">
            <arguments>
                <argument value="debug" type="string"/>
            </arguments>
        </listener>
    </listeners>
    
  2. Inspect Cassettes Manually validate YAML cassettes for correctness:

    cat tests/_cassettes/MyTest/testMethod.yaml
    

    Use php-vcr's VCR::play() to test replay outside PHPUnit:

    VCR::play('tests/_cassettes/MyTest/testMethod.yaml');
    
  3. Partial Recording Record only specific tests by combining with PHPUnit’s --filter:

    ./vendor/bin/phpunit --filter=testExternalApi --vcr-record=once
    

Extension Points

  1. Custom Listener Logic Extend the listener by subclassing Covergenius\TestListenerVcr\VcrListener and overriding methods like startTest() or endTest():

    class CustomVcrListener extends VcrListener {
        public function startTest(Test $test) {
            parent::startTest($test);
            // Custom logic, e.g., set cassette path dynamically
        }
    }
    
  2. Pre/Post-Record Hooks Use PHP-VCR’s hooks to modify interactions:

    VCR::beforeRecord(function ($interaction) {
        // Modify request/response before recording
    });
    
    VCR::afterRecord(function ($interaction) {
        // Post-process recorded data
    });
    
  3. Integration with Laravel

    • Service Provider: Bind the listener in AppServiceProvider:
      public function register() {
          $this->app->make('Covergenius\TestListenerVcr\VcrListener');
      }
      
    • Test Traits: Create a trait for reusable VCR setup:
      trait UsesVcr {
          protected function enableVcr() {
              VCR::configure()->setCassettePath('tests/_cassettes');
          }
      }
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky
spatie/mailcoach-vapor