Skip to content

feat: Add support for separate cassettes per DataProvider cases #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

cb-vova
Copy link

@cb-vova cb-vova commented Jul 18, 2025

This PR introduces comprehensive support for creating separate VCR cassettes for each PHPUnit DataProvider case, providing better isolation and organization of HTTP recordings in data-driven tests.

🚀 New Features

Enhanced UseCassette Attribute

  • separateCassettePerCase: When set to true, creates individual cassette files for each data provider case
  • groupCaseFilesInDirectory: When set to true, organizes separate cassette files in subdirectories

Flexible Cassette Naming Strategies

  • Numbered cases: cassette-0.yml, cassette-1.yml
  • Named cases: cassette-example-com.yml, cassette-example-org.yml
  • Directory organization: cassette/0.yml, cassette/example-com.yml
  • Extension handling: Works with and without file extensions

Class and Method Level Support

  • Works with UseCassette declared on test classes
  • Works with UseCassette declared on individual test methods
  • Maintains backward compatibility with existing usage

🔧 Implementation Details

Core Changes

  • UseCassette.php: Enhanced with new optional parameters
  • AttributeResolverTrait.php: Refactored to parse data provider information
  • StartRecording.php: Added intelligent cassette naming logic
  • New Value Objects: TestCaseParameters and TestMethodInfo for better data handling

Data Provider Name Normalization

  • Converts special characters to hyphens
  • Handles edge cases and invalid names
  • Maintains consistency across different naming patterns

📚 Documentation

  • Comprehensive README updates with multiple usage examples
  • Examples for all supported configurations
  • Clear migration path for existing users

🧪 Test Coverage

  • New Test Classes:
    • AttributeDeclaredOnClassWithSeparateCassettesInSeparateFoldersTest
    • AttributeDeclaredOnClassWithSeparateCassettesInSingleFolderTest
    • WithoutVcrTest
  • Enhanced Existing Tests: Updated AttributeDeclaredOnMethodsTest with new scenarios
  • Complete Fixture Set: 20+ test fixtures demonstrating all naming patterns and organization strategies

🔄 Backward Compatibility

  • All existing functionality remains unchanged
  • New parameters are optional with sensible defaults
  • No breaking changes to existing API

💡 Usage Examples

Basic Separate Cassettes

#[UseCassette(name: "api_test.yml", separateCassettePerCase: true)]
#[DataProvider("urls")]
public function testApiCalls(string $url): void
{
    // Creates: api_test-0.yml, api_test-1.yml
}

Organized in Directories

#[UseCassette(
    name: "api_test.yml", 
    separateCassettePerCase: true,
    groupCaseFilesInDirectory: true
)]
#[DataProvider("namedUrls")]
public function testApiCalls(string $url): void
{
    // Creates: api_test/example-com.yml, api_test/example-org.yml
}

This enhancement significantly improves the developer experience when working with data-driven tests that make HTTP requests, providing better isolation, easier debugging, and more organized test fixtures.

{
$test = explode(" ", $test)[0];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@angelov
I didn't get the idea of this explode. Why did you use it?
I removed this line because it doesn't allow us to have space in dataprovider cases.
for instance if my case is

yield 'My use case name' => [...]

It will result in dataProvider name 'my`

@angelov
Copy link
Owner

angelov commented Jul 29, 2025

Thank you for the contribution @cb-vova!

It's a bit of a busy period for me, but I will try to review this as soon as possible. In meanwhile, can you maybe split this into a few smaller PRs so it'll be easier to review?

@cb-vova cb-vova closed this Jul 29, 2025
@cb-vova cb-vova reopened this Jul 29, 2025
@cb-vova
Copy link
Author

cb-vova commented Aug 1, 2025

Thank you for the contribution @cb-vova!

It's a bit of a busy period for me, but I will try to review this as soon as possible. In meanwhile, can you maybe split this into a few smaller PRs so it'll be easier to review?

sure. the same thing..
I'll do my best to split, but other than splitting ci and code, I don't see many options to split. Only the 5 files are implemented, the others are tests 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants