Shopware 6插件单元测试中Composer依赖引发的命名空间冲突问题
Problem Description
I'm writing PHPUnit tests for a Shopware 6 plugin, and I've set up the PHPUnit environment exactly like SwagPayPal with these configurations:
- composer.json dependencies & autoload rules:
{ "require": { "ext-json": "*", "php": ">= 8.0", "goetas-webservices/xsd2php-runtime": "^0.2.16", "enqueue/stomp": "^0.10.16", "shopware/core": "6.4.12.0" }, "autoload": { "psr-4": { "Namespace\\Plugin\\": "src/" } }, "autoload-dev": { "psr-4": { "Namespace\\Plugin\\Test\\": "tests/" } } }
- phpunit.xml.dist uses
tests/TestBootstrap.phpas the bootstrap file, which is a copy of SwagPayPal's version minus the->addActivePlugins('SwagCmsExtensions')line.
All tests worked fine until I added this code to one test case:
$customerRepository = $this->getContainer()->get('customer.repository'); $customerRepository->upsert([$customerData], Context::createDefaultContext());
Now I get this compilation error after calling upsert:
Cannot declare class Shopware\Core\Checkout\Promotion\Cart\PromotionProcessor, because the name is already in use
Running sudo rm -rf var/cache/test_* fixes it for one run, but the error comes back on the second test execution. I've checked all namespace declarations in test files and they're correct—this seems to be a class loading conflict issue.
Root Cause Analysis
I've run into this exact issue before, and it boils down to duplicate class loading in the test environment. Here's what's happening:
- On the first run, no test cache exists, so the autoloader uses Shopware core classes from your project root directory.
- After the first run, the test cache stores class paths from your plugin's own
vendordirectory (which has a duplicate copy of Shopware core). - On the second run, the autoloader pulls the cached paths and tries to load the same core class twice, triggering the "class already in use" error.
Solutions
1. Fix Composer Dependencies to Avoid Duplicate Shopware Core
Your plugin doesn't need to include shopware/core in its require section—this pulls a duplicate copy into your plugin's vendor folder. Move it to require-dev instead, since it's only needed for testing:
Update your composer.json:
"require": { "ext-json": "*", "php": ">= 8.0", "goetas-webservices/xsd2php-runtime": "^0.2.16", "enqueue/stomp": "^0.10.16" }, "require-dev": { "shopware/core": "6.4.12.0" }, "prefer-stable": true
Then run:
rm -rf vendor/ composer install
2. Auto-Clean Test Cache in Bootstrap
Modify your tests/TestBootstrap.php to clear the test cache automatically before each run, so you don't have to do it manually:
// Add this at the top of TestBootstrap.php use Symfony\Component\Filesystem\Filesystem; // Force clean test cache $cacheDir = __DIR__ . '/../var/cache/test'; if (is_dir($cacheDir)) { $filesystem = new Filesystem(); $filesystem->remove($cacheDir); } // Rest of your bootstrap code (Kernel initialization, etc.)
3. Run Tests from the Shopware Project Root
Don't execute PHPUnit directly from your plugin directory. Instead, use the project root's PHPUnit binary to ensure it uses the project's autoloader:
cd /path/to/your/shopware/project ./vendor/bin/phpunit -c plugins/YourPluginName/phpunit.xml.dist
4. Verify PHPUnit Configuration
Double-check your phpunit.xml.dist to make sure it doesn't override the default autoloader behavior. It should only reference the bootstrap file:
<phpunit bootstrap="tests/TestBootstrap.php"> <!-- Your other test configurations here --> </phpunit>
Verification Steps
- Clear your plugin's
vendorfolder and test cache:rm -rf vendor/ var/cache/ - Run
composer installto refresh dependencies - Execute tests from the Shopware project root using the command above
- Run the tests multiple times to confirm the error doesn't reappear
内容的提问来源于stack exchange,提问作者RafaelKr

