🤖 AI-generated — created with Claude Code, reviewed by @Tabrisrp. Surfaced while migrating wp-media/mcp-oauth to wp-media/phpunit v3.2. Contributes to #30.
Problem
Consumer plugins ship their own near-identical base TestCase classes (Tests/Unit/TestCase.php, Tests/Integration/TestCase.php) that add a thin, fully generic test-data convenience layer on top of the library's existing getTestData(). The layer contains zero plugin-specific code, so it's pure duplicated boilerplate.
Current state
src/TestCaseTrait.php already provides getTestData($dir, $filename) (maps a Unit/Integration dir to the sibling Fixtures dir and requires the matching fixture file) and is used by both src/Unit/TestCase.php and src/Integration/TestCase.php.
Consumers typically add, on top of that:
protected $config; — holds the loaded fixture.
configTestData(): array — returns $this->config['test_data'] ?? $this->config; used as a PHPUnit @dataProvider.
loadTestDataConfig(): void — new ReflectionObject($this) to find the current test file, then $this->config = $this->getTestData( dirname($file), basename($file, '.php') ).
Some also override set_up() to eagerly call loadTestDataConfig().
Evidence it's pure, duplicated boilerplate
- In wp-media/mcp-oauth, the Unit and Integration
TestCase.php files are identical except for the namespace and the visibility of set_up() (protected in Unit, public in Integration). The only project-specific token in either file is the namespace line.
- 35 test files consume this solely via
@dataProvider configTestData; zero tests read $this->config directly in a test body. So the eager set_up() hook is redundant — data providers run before set_up(), and configTestData() already lazy-loads when $config is empty.
Proposed solution
Move $config, configTestData(), and loadTestDataConfig() into src/TestCaseTrait.php, right next to the getTestData() they depend on. Both Unit\TestCase and Integration\TestCase already use TestCaseTrait, so they inherit it automatically.
Do not add a set_up() hook inside the trait: it's unnecessary (lazy-loading via configTestData() covers all real usage) and would collide with the differing set_up() signatures/visibility of the Brain\Monkey (Unit) vs WP-integration (Integration) base classes.
Impact
Consumers can then delete both Tests/{Unit,Integration}/TestCase.php and extend WPMedia\PHPUnit\Unit\TestCase / WPMedia\PHPUnit\Integration\TestCase directly (a one-line use/extends change per test file, or a one-line project alias during migration). This advances the #30 goal of moving common, non-plugin-specific test infrastructure into the library.
References
Contributes to #30.
Problem
Consumer plugins ship their own near-identical base
TestCaseclasses (Tests/Unit/TestCase.php,Tests/Integration/TestCase.php) that add a thin, fully generic test-data convenience layer on top of the library's existinggetTestData(). The layer contains zero plugin-specific code, so it's pure duplicated boilerplate.Current state
src/TestCaseTrait.phpalready providesgetTestData($dir, $filename)(maps aUnit/Integrationdir to the siblingFixturesdir andrequires the matching fixture file) and is used by bothsrc/Unit/TestCase.phpandsrc/Integration/TestCase.php.Consumers typically add, on top of that:
protected $config;— holds the loaded fixture.configTestData(): array— returns$this->config['test_data'] ?? $this->config; used as a PHPUnit@dataProvider.loadTestDataConfig(): void—new ReflectionObject($this)to find the current test file, then$this->config = $this->getTestData( dirname($file), basename($file, '.php') ).Some also override
set_up()to eagerly callloadTestDataConfig().Evidence it's pure, duplicated boilerplate
TestCase.phpfiles are identical except for the namespace and the visibility ofset_up()(protectedin Unit,publicin Integration). The only project-specific token in either file is thenamespaceline.@dataProvider configTestData; zero tests read$this->configdirectly in a test body. So the eagerset_up()hook is redundant — data providers run beforeset_up(), andconfigTestData()already lazy-loads when$configis empty.Proposed solution
Move
$config,configTestData(), andloadTestDataConfig()intosrc/TestCaseTrait.php, right next to thegetTestData()they depend on. BothUnit\TestCaseandIntegration\TestCasealreadyuse TestCaseTrait, so they inherit it automatically.Do not add a
set_up()hook inside the trait: it's unnecessary (lazy-loading viaconfigTestData()covers all real usage) and would collide with the differingset_up()signatures/visibility of the Brain\Monkey (Unit) vs WP-integration (Integration) base classes.Impact
Consumers can then delete both
Tests/{Unit,Integration}/TestCase.phpand extendWPMedia\PHPUnit\Unit\TestCase/WPMedia\PHPUnit\Integration\TestCasedirectly (a one-lineuse/extendschange per test file, or a one-line project alias during migration). This advances the #30 goal of moving common, non-plugin-specific test infrastructure into the library.References
Contributes to #30.