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

php-vcr/phpunit-testlistener-vcr

PHPUnit TestListener integrating PHP-VCR via @vcr annotations. Automatically turns VCR on/off per test and records/replays HTTP interactions using named cassettes. Install with Composer and register the listener in phpunit.xml.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package Add the package via Composer:

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

    Ensure php-vcr/php-vcr is also installed (required dependency).

  2. Configure PHP-VCR Create a php-vcr.yml (or php-vcr.php) in your project root:

    # php-vcr.yml
    storage: ./tests/vcr_cassettes
    record_if: env(RECORD) == 'true'
    
  3. Enable the Listener Add the listener to your phpunit.xml:

    <phpunit>
        <extensions>
            <extension class="PHPVCR\PHPUnit\TestListenerVCR"/>
        </extensions>
    </phpunit>
    
  4. First Use Case: Record a Test Run tests with RECORD=true to generate cassettes:

    RECORD=true ./vendor/bin/phpunit
    

    Subsequent runs will replay recorded responses.


Implementation Patterns

Workflow: Test-Driven API Development

  1. Record Initial Requests Write a test for an API endpoint, then record the response:

    // tests/Feature/UserTest.php
    public function test_fetch_user()
    {
        $response = $this->get('/api/user/1');
        $response->assertStatus(200);
    }
    

    Run with RECORD=true to save the cassette.

  2. Update Cassettes When Needed Use RECORD=update to modify cassettes for changed responses:

    RECORD=update ./vendor/bin/phpunit tests/Feature/UserTest
    
  3. Conditional Recording Use record_if in php-vcr.yml to control when to record:

    record_if: env(RECORD) == 'true' || env(GITHUB_ACTIONS) == 'true'
    

Integration with Laravel

  • HTTP Client Mocking Replace Http::fake() with VCR for realistic HTTP interactions:

    use PHPVCR\VCR;
    
    public function test_external_payment()
    {
        VCR::turnOn();
        $response = Http::post('https://payment-gateway.com/charge', [...]);
        $response->assertOk();
    }
    
  • Database + API Tests Combine with Laravel’s database transactions:

    public function test_order_flow()
    {
        $this->actingAs($user);
        VCR::turnOn();
        $response = $this->post('/orders', [...]);
        $response->assertCreated();
    }
    

Parallel Testing

  • Use VCR::turnOn() per test class or method to isolate cassettes:
    class PaymentTest extends TestCase
    {
        protected function setUp(): void
        {
            VCR::turnOn();
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Cassette Naming Collisions

    • Default naming: {classname}_{methodname}.yaml.
    • Fix: Customize naming in php-vcr.yml:
      cassette_namer: 'tests/vcr_cassettes/%s/%s.yaml'
      
  2. Dynamic Data Leaking

    • Avoid recording non-deterministic data (e.g., timestamps, UUIDs).
    • Fix: Use ignore_header or ignore_body in php-vcr.yml:
      ignore_header:
          - Date
          - Authorization
      
  3. Slow Tests on CI

    • Replaying cassettes is fast, but recording is slow.
    • Fix: Skip recording in CI unless explicitly needed:
      record_if: env(RECORD) == 'true' || env(LOCAL) == 'true'
      
  4. Laravel’s HTTP Client Quirks

    • Ensure Http::baseUrl() is consistent across environments.
    • Fix: Set a fixed base URL in tests:
      Http::baseUrl('https://staging.example.com');
      

Debugging

  • Verify Cassettes Check recorded cassettes in ./tests/vcr_cassettes/ for correctness. Use VCR::debug() to log interactions:

    VCR::debug(function ($interaction) {
        dump($interaction->getUri(), $interaction->getBody());
    });
    
  • Reset Cassettes Delete the cassette directory to force re-recording:

    rm -rf tests/vcr_cassettes/*
    

Extension Points

  1. Custom Matchers Extend PHPVCR\VCR\Matcher\MatcherInterface to ignore dynamic fields:

    class IgnoreTimestampMatcher implements MatcherInterface
    {
        public function matches($expected, $actual) { ... }
    }
    

    Register in php-vcr.yml:

    matchers:
        - PHPVCR\VCR\Matcher\IgnoreTimestampMatcher
    
  2. Pre/Post-Request Hooks Use VCR::beforeRecord() and VCR::afterRecord() for setup/teardown:

    VCR::beforeRecord(function ($interaction) {
        $interaction->setBody(json_encode([
            'user_id' => auth()->id(),
        ]));
    });
    
  3. Environment-Specific Config Load different php-vcr.yml files per environment:

    # php-vcr.local.yml
    storage: ./tests/vcr_cassettes/local
    
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