Add unit and functional test suites - #87
Merged
Merged
Conversation
- phpunit.xml.dist defines a "unit" suite (tests/Unit, no database) and a "functional" suite (tests/Functional, boots the test application). Functional tests run inside a transaction that dama/doctrine-test-bundle rolls back. - Unit tests (Prophecy) cover the DI extension/configuration/compiler pass, the model, context, provider, admin menu, fixture + example factory, form type, all Conversions API events and all event subscribers. - Functional tests cover PixelRepository::findEnabledByChannel(), the pixel fixture and the admin CRUD (list/create/validate/update/delete/auth) through the Symfony test client. - Test application: register DAMADoctrineTestBundle in the test environments, do not require built frontend assets in tests, and fix config/bootstrap.php to require_once the Composer autoloader (the previous require redeclared the autoloader under Infection, turning every mutant into a fatal error). - Small behaviour-preserving simplifications to make branches testable: main taxon fallback via getTaxons()->first(), integer cents divided by 100 without rounding, LimitIterator instead of a counter/break. - Infection now runs at 100% MSI; equivalent mutants (defensive string casts, type-narrowing asserts, trait method visibility) are ignored explicitly. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
The unit tests job runs the unit suite, the integration tests job runs the functional suite after creating the schema, and the coverage and mutation jobs start MySQL and create the schema so the functional tests are included. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
loevgaard
commented
Aug 31, 2026
loevgaard
commented
Aug 31, 2026
loevgaard
commented
Aug 31, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 3.x #87 +/- ##
==============================================
+ Coverage 0.00% 100.00% +100.00%
+ Complexity 113 110 -3
==============================================
Files 25 25
Lines 419 400 -19
==============================================
+ Hits 0 400 +400
+ Misses 419 0 -419 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
loevgaard
commented
Aug 31, 2026
In CI the test container is already compiled by the schema creation steps, so booting the kernel in the functional tests never executed SetonoSyliusFacebookPlugin::build()/getSupportedDrivers() under coverage and Infection reported their mutants as uncovered. Test the bundle class directly instead of relying on the container cache state. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
payum/payum-bundle 2.7.0 replaced its XML routing files with YAML, which breaks the @PayumBundle/Resources/config/routing/*.xml imports in Sylius 1.14's shop routing; 2.7.1 restored the XML files as a backwards compatibility layer. The "lowest" dependency resolution in CI landed on exactly 2.7.0, so the functional tests could not build the router. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
…checks The integration, coverage and mutation jobs now install Node (from tests/Application/.nvmrc) and run yarn install && yarn build before the functional tests, so the test environment no longer needs to disable Webpack Encore's strict mode or drop the asset manifests. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
Without ignores the suite kills 165 of 186 mutants (MSI 88.7%); the remaining 21 are defensive (string) casts of nullable getters, type-narrowing asserts after OptionsResolver/DQL validation and the trait method visibility. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
Running Infection single-threaded (as CI does) kills 162 of 186 mutants (87.1%); the earlier 88.7% measured locally with four threads counted three equivalent mutants as killed because parallel functional tests collided on the same unique channel codes in the shared test database. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
Replaces the payum/payum-bundle version constraint: instead of going through
Sylius' XML-only payum.yml, the test application imports the same three Payum
routing files with a {xml,yaml} glob, so it works with payum-bundle 2.7.0
(YAML only) as well as with < 2.7 (XML only) and >= 2.7.1 (both).
Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
…cation" The require-dev constraint "payum/payum-bundle": "^2.6 !=2.7.0" is the simpler way to keep payum-bundle 2.7.0 (YAML-only routing, incompatible with Sylius 1.14's imports) out of the test application, and it keeps the test application's shop routing identical to Sylius'. This reverts commit b0d2b9a. Claude-Session: https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS
loevgaard
force-pushed
the
add-test-suites
branch
from
August 31, 2026 10:03
ccdd888 to
a777f5e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a real test setup: a
unitand afunctionalPHPUnit suite, with database-backed functional tests isolated by dama/doctrine-test-bundle (every test runs in a transaction that is rolled back).Suites
unit(tests/Unit, no database) — Prophecy-based, BDD-style test names:Configuration,SetonoSyliusFacebookExtension,OverrideDefaultPixelProviderPassPixelmodel,PixelContext,DoctrineBasedPixelProvider,AdminMenuListenerPixelFixture,PixelExampleFactory,PixelType(SymfonyTypeTestCase)ProductViewed,CategoryViewed,ProductAddedToCart,OrderPlaced,CheckoutStarted)EventSubscriber::track()functional(tests/Functional, boots the test application) — a smallFunctionalTestCasecreates the channel/admin user/pixels it needs inside the transaction:PixelRepository::findEnabledByChannel()setono_facebook_pixelfixture end-to-endTest application
DAMADoctrineTestBundleregistered fortest/test_cached, PHPUnit extension inphpunit.xml.distconfig/packages/test/{assets,webpack_encore}.yaml: functional tests do not need a frontend build (verified withpublic/buildremoved, i.e. CI conditions)config/bootstrap.php:require_oncethe Composer autoloader with a sane path. The previousrequire dirname(__DIR__) . '../../../vendor/autoload.php'redeclared the autoloader under Infection, so every mutant died with a fatal error — the mutation job could never have produced a real result.src/— small behaviour-preserving simplifications to make branches testablegetTaxonName()in the product events:getMainTaxon() ?? getTaxons()->first()FormatAmountTrait: amounts are integer cents, so$amount / 100is exact and needs noround()ViewCategorySubscriber:LimitIteratorinstead of a counter +breakMutation testing
Infection now runs at 100% MSI (157 mutants killed, 0 escaped, 0 uncovered). Equivalent mutants are ignored explicitly in
infection.json.dist:CastStringon the defensive(string)casts of nullable getters inEvent\*/ the pixel provider,MethodCallRemovalfor the type-narrowingAsserts that follow OptionsResolver/DQL validation, andProtectedVisibilityonFormatAmountTrait::formatAmount()(keptprotectedfor subclasses ofOrderBasedEvent).CI
Unit job runs
--testsuite unit; integration job runs--testsuite functionalafter creating the schema; coverage and mutation jobs now start MySQL and create the schema so the functional suite is included.Dependencies (dev)
dama/doctrine-test-bundle ^7.3(v8 requires PHPUnit ≥ 10, the plugin pack pins 9.6),symfony/browser-kit,symfony/css-selector.Verified locally on PHP 8.3: 81 tests green, ECS, PHPStan (level max), Rector, Infection 100%.
https://claude.ai/code/session_013jh2QjzkxAJABPDYB1UiPS