Weave 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

Test Application Laravel Package

sylius/test-application

Sylius Test Application provides a ready-made Sylius ecommerce environment for package development, with a minimal application skeleton and configuration for running functional tests and validating Sylius components and plugins in realistic conditions.

View on GitHub
Deep Wiki
Context7

Getting Started

Add the package as a dev-only dependency — it should never ship in production builds:

composer require --dev sylius/test-application

The package is no longer fully version-agnostic. As of v2.2.0-ALPHA.1, the 2.2 line explicitly pins sylius/sylius to the 2.2 series (PR #43, "Lock Sylius version to 2.2"). The package is maintained in parallel branches (2.0, 2.1, 2.2) with regular upmerges, so the package branch you install now determines the Sylius version you test against. Pick the line that matches the Sylius version your plugin supports:

Your plugin supports Install
Sylius 2.2 sylius/test-application:^2.2@alpha (alpha — see below)
Sylius 2.1 sylius/test-application:^2.1
Sylius 2.0 sylius/test-application:^2.0

Two things to know before your first composer require:

  • v2.2.0-ALPHA.1 is a pre-release. A plain ^2.2 constraint will not resolve it unless you allow alpha stability for the package ("minimum-stability": "alpha" plus "prefer-stable": true, or an explicit @alpha flag). Pin the tag if you need reproducibility.
  • If your root composer.json already requires a Sylius version outside the pinned range, Composer will now fail to resolve rather than quietly testing against the wrong version. That's a behaviour change from earlier 2.x releases — expect it on the first install.

Look first at:

  1. The shipped Kernel class (usually Sylius\TestApplication\Kernel) — this is the entry point your test suite boots.
  2. The package's config/ directory — bundles, framework config, and Sylius core config live there. Read config/packages/twig.yaml in particular; the 2.2 line added a default_path (PR #40).
  3. Any provided bin/console / public/index.php stubs — these tell you what the package expects for paths (var/cache, var/log, config/).

First use case — a smoke test that the app boots and the container compiles:

# from your plugin root
APP_ENV=test php vendor/bin/console about

If that succeeds, you already have a working Sylius application. Next, point PHPUnit at the same kernel:

<!-- phpunit.xml.dist -->
<php>
    <env name="APP_ENV" value="test"/>
    <env name="KERNEL_CLASS" value="Sylius\TestApplication\Kernel"/>
    <env name="DATABASE_URL" value="mysql://[email protected]:3306/sylius_test"/>
</php>

Then write a KernelTestCase that boots it and asserts your plugin's bundle is registered:

final class BundleRegistrationTest extends KernelTestCase
{
    protected static function getKernelClass(): string
    {
        return \Sylius\TestApplication\Kernel::class;
    }

    public function test_my_plugin_is_registered(): void
    {
        self::bootKernel();
        self::assertTrue(self::$kernel->getContainer()->has('my_plugin.service'));
    }
}

That is the minimum viable loop: install → boot the kernel → assert your services/bundles exist.

Implementation Patterns

Pattern 1: Overlay config instead of forking the package

Do not copy the package's config/ into your repo. Instead, add project-specific overrides in tests/Application/config/ and import them from your test config, or use a small custom kernel that extends the package kernel:

namespace App\Tests\Application;

use Sylius\TestApplication\Kernel as BaseKernel;

final class Kernel extends BaseKernel
{
    public function registerBundles(): iterable
    {
        $bundles = iterator_to_array(parent::registerBundles());
        $bundles[] = new \Acme\SyliusMyPlugin\AcmeSyliusMyPlugin();

        return $bundles;
    }
}

This keeps you insulated from upstream changes — which now arrive on a per-Sylius-version cadence — while still benefiting from the package's shared wiring.

Pattern 2: Plugin's own bundle registration via config

If you don't need a custom kernel, register your bundle through config/bundles.php in the test app, guarded so it only loads in test:

<?php
// tests/Application/config/bundles.php
$bundles = require __DIR__ . '/../../vendor/sylius/test-application/config/bundles.php';

if ('test' === ($_SERVER['APP_ENV'] ?? 'dev')) {
    $bundles[\Acme\SyliusMyPlugin\AcmeSyliusMyPlugin::class] = ['all' => true];
}

return $bundles;

Pattern 3: Shared database with transactional isolation

Do not recreate the schema for every test. Bootstrap once, then wrap each test:

php vendor/bin/console doctrine:database:create --if-not-exists
php vendor/bin/console doctrine:schema:create
php vendor/bin/console sylius:fixtures:load --no-interaction

Then use dama/doctrine-test-bundle (or a beginTransaction/rollBack in setUp/tearDown) to roll back after each test. This turns a 30-second suite into a 3-second one.

Pattern 4: Fixture loading via Sylius test traits

Sylius ships fixture/purger traits (LoadDataFixturesTrait, PurgerTrait, etc.). Combine them with the test-application kernel so your functional tests can seed a cart, an order, or a channel deterministically:

use Sylius\Bundle\CoreBundle\Test\Services\SharedStorageInterface;
use Sylius\Bundle\CoreBundle\Test\Services\EmailCheckerInterface;

protected function setUp(): void
{
    parent::setUp();
    $this->purger = self::getContainer()->get('sylius.fixture.purger');
}

Pattern 5: CI matrix over package branches, not Sylius constraints

The old "matrix over Sylius versions with one package release" approach is dead as of the 2.2 line — the package now pins its Sylius counterpart. Matrix over package branches instead, one job per supported Sylius line:

strategy:
  matrix:
    include:
      - test-app: '^2.0'
        sylius: '^2.0'
      - test-app: '^2.1'
        sylius: '^2.1'
      - test-app: '^2.2@alpha'
        sylius: '^2.2'
steps:
  - run: composer require --no-update --dev "sylius/test-application:${{ matrix.test-app }}"
  - run: composer require --no-update "sylius/sylius:${{ matrix.sylius }}"
  - run: composer update --prefer-dist
  - run: php vendor/bin/console doctrine:schema:create
  - run: php vendor/bin/phpunit

Each row validates one branch of your support claim. When Sylius ships 2.3, a matching package branch should follow — add the row then, and drop the oldest.

Pattern 6: Behat + test-application

Point Behat's KernelContext at the package kernel and let sylius/behat bootstrap its services. Set APP_ENV=test in behat.yml and reuse the same database between scenarios where you can, resetting with the purger otherwise.

Gotchas and Tips

  • The Sylius pin is the headline change. From v2.2.0-ALPHA.1 onward the package locks Sylius (2.2 for this line). If your plugin claims ^1.12 || ^2.0 || ^2.1, you cannot develop against the 2.2 package branch — install the matching branch instead. Symptom of getting this wrong: a Composer conflict at require time, or (worse, on older branches) a green suite that tested a Sylius version you don't support.

  • Alpha stability. ^2.2 resolves to 2.2.0-ALPHA.1 only with an explicit stability allowance. In CI, pin sylius/test-application:v2.2.0-ALPHA.1 so a new alpha doesn't silently change your Sylius version mid-sprint.

  • Twig default_path is new (PR #40). The 2.2 line sets a Twig default_path. If your plugin overrides templates and relied on the previous implicit path resolution, verify with php vendor/bin/console debug:config twig and, if needed, set twig.default_path in your own tests/Application/config/packages/twig.yaml override. Bundle-scoped twig.paths are unaffected.

  • Cache directory bleed. PHPUnit runs in the project, but the kernel's cache dir may default to a var/cache/test inside vendor/ — read-only in some CI setups and not cleared between runs. Override getCacheDir() / getLogDir() in your kernel to point at tests/Application/var/.

  • Clear cache between package branches. With a branch matrix, always rm -rf tests/Application/var/cache between jobs (and locally when switching branches). Stale container caches are the #1 source of "works locally, fails in CI."

  • APP_ENV is not enough. Ensure APP_DEBUG=0 in CI — the debug container rebuilds on every request and can make functional tests 5–10× slower.

  • Bundle order matters. Sylius's compiler passes expect SyliusCoreBundle before SyliusAdminBundle before your own admin-extending bundle. If you get "Service X not found" errors, check registration order, not the service definition.

  • Migrations vs. schema tool. Sylius's doctrine:schema:create and doctrine:migrations:migrate are not equivalent — if your plugin ships migrations, test them explicitly with migrations:migrate in a separate CI job.

  • Database isolation. Tests that hit the DB will clobber fixtures if you don't roll back. Prefer dama/doctrine-test-bundle over hand-rolled TRUNCATE — it's faster and handles nested transactions.

  • Debugging the container. When something is missing:

    php vendor/bin/console debug:container --tag=sylius.repository
    php vendor/bin/console debug:config framework
    php vendor/bin/console debug:config twig
    php vendor/bin/console lint:container
    

    lint:container is by far the fastest way to catch DI errors introduced by your bundle.

  • Extension points. If you need a fixture or service only available in tests, prefer decorating in tests/Application/config/services_test.yaml rather than modifying the package. The package's kernel exposes configureContainer() — override it if you need early binding.

  • Don't commit tests/Application/var/ or composer.lock in the test app. Treat the test application as generated output; the source of truth is your config/ overrides plus composer.json.

  • Upmerges mean churn is normal. Releases routinely carry 2.0 -> 2.1 -> 2.2 upmerges (PRs #42, #44, #45, #46 in this release alone). Diffing a new tag is noisy; filter for the branch you're on, and read the "Lock Sylius version" / maintenance PRs first — those are the ones that change your constraints.

  • Low-traffic upstream. The package still has very few stars and dependents, so breakage won't be loudly reported. After any new tag, boot your test app on a scratch branch before merging — a console about plus one lint:container run catches most of it in under a minute.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons