Teststrategie für Hyvä-Themes: Testpyramide von PHPUnit bis Playwright
AI generated
Hyvä
phtml
Hyvä · Testing · CI/CD · Playwright
Teststrategie für Hyvä-Themes
von PHPUnit bis Playwright E2E

Hyvä hat keine Knockout-Viewmodels und damit auch keine klassische JavaScript-Unit-Test-Ebene, die man aus Luma-Themes kennt. Wer eine Teststrategie für Hyvä-Themes aufbaut, muss die Testpyramide deshalb neu denken: PHPUnit prüft die PHP-Logik hinter den ViewModels, PHPStan fängt Typfehler ab, bevor überhaupt ein Test läuft, und Playwright deckt genau die Alpine.js-Interaktion im echten Browser ab, für die es in Hyvä sonst keine sinnvolle Unit-Test-Ebene gibt.

17 Min. Lesezeit PHPUnit · PHPStan · Playwright · axe-core Magento 2.4.8 · Hyvä Themes

1. Die Testpyramide im Hyvä-Kontext

Die klassische Testpyramide setzt auf eine breite Basis aus schnellen Unit-Tests, eine schmalere Schicht Integrationstests und eine dünne Spitze aus langsamen End-to-End-Tests. In einem Luma-Theme mit Knockout.js hätte diese Basis auch eine JavaScript-Unit-Test-Ebene für Viewmodels enthalten, deren Observable-Ketten und Subscriptions isoliert getestet werden konnten. Genau diese Ebene fehlt in einer Teststrategie für Hyvä-Themes, weil Hyvä bewusst auf Knockout-Viewmodels verzichtet und stattdessen serverseitige PHP-ViewModels nutzt, die fertig berechnete Werte direkt ins phtml-Template und von dort in schlanke Alpine.js-Komponenten reichen.

Das verschiebt die gesamte Pyramide. Die eigentliche Berechnungslogik, Preisformatierung, Sichtbarkeitsflags, Badge-Texte, Rabattlogik, sitzt in PHP-Klassen und lässt sich mit PHPUnit vollständig isoliert testen, ohne Browser und ohne DOM. Wer ein Hyvä-Theme testen will, sollte diese PHP-Schicht deshalb als eigentliche Unit-Test-Basis behandeln, nicht die dünnen Alpine.js-Snippets im Template, die kaum eigene Logik enthalten. Alpine übernimmt in Hyvä fast ausschließlich UI-Zustand: ein Dropdown öffnen, eine Klasse toggeln, einen Wert aus dem DOM lesen. Diese Interaktionen ergeben isoliert getestet wenig Sinn, weil ihr gesamter Wert erst im Zusammenspiel mit echtem HTML, echtem CSS und einem echten Browser-Event-Loop entsteht.

Die Konsequenz für jede Testing-Strategie im Hyvä-Theme: PHPStan und PHPUnit bilden eine breite, schnelle Basis für die PHP-Seite, während End-to-End-Tests mit Playwright einen deutlich größeren Anteil der Pyramide einnehmen als in Frameworks mit eigener JS-Unit-Test-Kultur üblich. Darüber legen sich zwei spezialisierte Schichten, visuelle Regression für Tailwind-Layouts und CSP-Regressionstests für Hyväs strikte Content-Security-Policy, die beide ohne echten Browser nicht sinnvoll umsetzbar sind.

2. PHPUnit für ViewModels

Wer eine Teststrategie für Hyvä-Themes aufbaut, sollte PHPUnit konsequent auf die ViewModels ansetzen, die per ArgumentInterface Daten an phtml-Templates liefern. Genau diese Klassen entscheiden, ob ein Rabatt-Badge angezeigt wird, wie ein Preis formatiert ist oder ob ein Versandhinweis erscheint, alles Werte, die direkt in Bedingungen und Ausgaben im Template landen. Ein Bug in einer solchen Berechnung ist im Frontend oft nur schwer sichtbar, während ein PHPUnit-Test ihn in Millisekunden aufdeckt, lange bevor ein Playwright-Lauf überhaupt startet.

Konstruktor-Property-Promotion in PHP 8.4 macht ViewModels und ihre Tests gleichermaßen kompakt: Abhängigkeiten wie ein PricingHelper oder ein StoreManagerInterface werden als readonly-Properties injiziert, im Test per Mock-Objekt ersetzt und im setUp() einmalig zusammengesteckt. Wichtig ist, jede öffentliche Methode des ViewModels mit mehreren Datenpunkten zu testen, nicht nur den Erfolgsfall: leerer Warenkorb, Grenzwert für kostenlosen Versand, negative Rabatte, fehlende Übersetzungen. Wer ein Hyvä-Theme testen will, ohne diese Randfälle abzudecken, verlagert das Debugging faktisch in die Produktion.


<?php

declare(strict_types=1);

namespace Mironsoft\Testing\ViewModel;

use Magento\Framework\Pricing\Helper\Data as PricingHelper;
use Magento\Framework\View\Element\Block\ArgumentInterface;

/**
 * Computes the free-shipping hint and formatted subtotal for the mini-cart template.
 */
final class MiniCartSummary implements ArgumentInterface
{
    private const FREE_SHIPPING_THRESHOLD = 49.0;

    /**
     * @param PricingHelper $pricingHelper Formats amounts using the store currency
     */
    public function __construct(
        private readonly PricingHelper $pricingHelper
    ) {
    }

    /**
     * Decides whether the free-shipping hint should be rendered.
     *
     * @param float $subtotal Cart subtotal excluding shipping
     * @return bool True if the subtotal is below the free-shipping threshold
     */
    public function shouldShowFreeShippingHint(float $subtotal): bool
    {
        return $subtotal > 0.0 && $subtotal < self::FREE_SHIPPING_THRESHOLD;
    }

    /**
     * Formats the missing amount until free shipping is reached.
     *
     * @param float $subtotal Cart subtotal excluding shipping
     * @return string Formatted currency amount, empty string if threshold already reached
     */
    public function formatMissingAmount(float $subtotal): string
    {
        $missing = self::FREE_SHIPPING_THRESHOLD - $subtotal;

        return $missing > 0.0 ? $this->pricingHelper->currency($missing, true, false) : '';
    }
}

<?php

declare(strict_types=1);

namespace Mironsoft\Testing\Test\Unit\ViewModel;

use Magento\Framework\Pricing\Helper\Data as PricingHelper;
use Mironsoft\Testing\ViewModel\MiniCartSummary;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
 * Unit tests for MiniCartSummary, covers the computed values consumed by minicart.phtml.
 */
final class MiniCartSummaryTest extends TestCase
{
    private PricingHelper&MockObject $pricingHelper;
    private MiniCartSummary $viewModel;

    /**
     * Builds the ViewModel fixture with a mocked pricing dependency.
     *
     * @return void
     */
    protected function setUp(): void
    {
        $this->pricingHelper = $this->createMock(PricingHelper::class);
        $this->viewModel = new MiniCartSummary($this->pricingHelper);
    }

    /**
     * @dataProvider subtotalProvider
     */
    public function testShouldShowFreeShippingHint(float $subtotal, bool $expected): void
    {
        self::assertSame($expected, $this->viewModel->shouldShowFreeShippingHint($subtotal));
    }

    /**
     * Provides edge cases for the free-shipping threshold at 49.00.
     *
     * @return array<string, array{0: float, 1: bool}>
     */
    public static function subtotalProvider(): array
    {
        return [
            'empty cart' => [0.0, false],
            'just below threshold' => [48.99, true],
            'exactly at threshold' => [49.0, false],
            'above threshold' => [65.0, false],
        ];
    }

    public function testFormatMissingAmountReturnsEmptyStringAboveThreshold(): void
    {
        $this->pricingHelper->expects(self::never())->method('currency');

        self::assertSame('', $this->viewModel->formatMissingAmount(60.0));
    }
}

3. PHPStan als schnelles erstes Gate

Bevor überhaupt ein PHPUnit-Test läuft, sollte in jeder Teststrategie für Hyvä-Themes ein PHPStan-Lauf auf Level 5 oder höher stehen. Statische Analyse findet eine ganze Klasse von Fehlern, die PHPUnit erst durch echte Testfälle aufdecken würde: falsch typisierte Parameter, aufgerufene Methoden, die auf dem Interface gar nicht existieren, oder ein ViewModel, das ein Array statt eines erwarteten Objekts an das Template zurückgibt. Der Lauf dauert wenige Sekunden statt Minuten und ist damit das mit Abstand günstigste Gate in der gesamten Pipeline.

ViewModels profitieren davon besonders, weil sie ohne Typprüfung durch das Interface direkt in phtml-Templates konsumiert werden, dort, wo PHP keine strikte Typprüfung mehr erzwingt. Ein Aufruf wie $viewModel->getPrice() im Template kompiliert immer, auch wenn die Methode längst umbenannt wurde, der Fehler zeigt sich sonst erst als leere Ausgabe im Browser. PHPStan mit bin/analyse app/code/Mironsoft/Testing --level=5 fängt genau das schon beim Commit ab. Bekannte Magento-Interface-Lücken wie StoreManagerInterface::getStores() mit falschen Stubs werden projektweit mit typisierten @var-Annotationen statt mit assert() gelöst, echte Interface-Lücken wie PageInterface::getData() mit einem dokumentierten @phpstan-ignore-next-line.

4. E2E-Tests mit Playwright für Alpine.js-Flows

Alpine.js-Direktiven wie x-data, x-show, x-model und x-transition entfalten ihre eigentliche Wirkung erst im DOM eines echten Browsers, mit CSS-Übergängen, Event-Bubbling und dem Zusammenspiel mehrerer Komponenten auf derselben Seite. Ein isolierter JavaScript-Unit-Test außerhalb des Browsers kann bestenfalls die reine Store-Logik prüfen, nicht aber, ob ein Klick auf "In den Warenkorb legen" tatsächlich das Mini-Cart-Icon aktualisiert, eine Animation auslöst und den Fokus korrekt setzt. Genau deshalb ist Playwright der zentrale Baustein jeder Teststrategie für Hyvä-Themes: Es rendert die Seite in einem echten Chromium-, Firefox- oder WebKit-Kontext und interagiert mit ihr wie ein Nutzer.

Die relevanten Flows für ein Hyvä-Theme sind überschaubar, aber kritisch: Warenkorb-Interaktionen im Mini-Cart, der komplette Checkout-Trichter über mehrere Schritte, Live-Search mit Autocomplete-Vorschlägen und die Facetten-Navigation auf Kategorieseiten inklusive URL-Synchronisation. Für stabile Selektoren gilt projektweit die Konvention, jedes interaktive Element im phtml-Template mit einem data-testid-Attribut auszuzeichnen, unabhängig von CSS-Klassen, die sich mit jedem Tailwind-Refactoring ändern können.


<?php
/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
/** @var \Hyva\Theme\ViewModel\HyvaCsp $hyvaCsp */
$hyvaCsp = $viewModels->require(\Hyva\Theme\ViewModel\HyvaCsp::class);
?>
<!-- File: templates/minicart/minicart.phtml -->
<div x-data="miniCart()" class="relative" data-testid="minicart-root">
    <button
        type="button"
        x-on:click="toggle()"
        class="relative p-2"
        data-testid="minicart-toggle"
    >
        <span class="sr-only">Warenkorb oeffnen</span>
        <span
            x-show="itemCount > 0"
            x-text="itemCount"
            class="absolute -top-1 -right-1 bg-orange-600 text-white text-xs rounded-full px-1.5"
            data-testid="minicart-count"
        ></span>
    </button>

    <div
        x-show="open"
        x-transition
        x-cloak
        class="absolute right-0 mt-2 w-80 bg-white rounded-xl shadow-xl"
        data-testid="minicart-drawer"
    >
        <template x-for="item in items" x-bind:key="item.sku">
            <div class="flex justify-between p-3" data-testid="minicart-line-item">
                <span x-text="item.name"></span>
                <span x-text="item.qty"></span>
            </div>
        </template>
    </div>
</div>

<script>
    // Registers the Alpine component factory for the mini-cart drawer
    function miniCart() {
        return {
            open: false,
            itemCount: 0,
            items: [],
            toggle() { this.open = !this.open; },
        };
    }
</script>
<?php /* Mandatory after every inline script block in a Hyva theme */ ?>
<?= $hyvaCsp->registerInlineScript() ?>

// File: tests/e2e/minicart.spec.ts
import { test, expect } from '@playwright/test';

test.describe('Mini-cart Alpine.js flow', () => {
  test('adds a product to the mini-cart and updates the badge count', async ({ page }) => {
    await page.goto('/catalog/product/view/id/42');

    // Trigger the add-to-cart action rendered by the Hyva product template
    await page.getByTestId('add-to-cart').click();

    // Alpine reactivity should reflect the new state without a page reload
    await expect(page.getByTestId('minicart-count')).toHaveText('1');

    // Open the drawer and verify the line item rendered from the store
    await page.getByTestId('minicart-toggle').click();
    await expect(page.getByTestId('minicart-drawer')).toBeVisible();
    await expect(page.getByTestId('minicart-line-item')).toContainText('Product Name');
  });

  test('removes the last item and hides the badge again', async ({ page }) => {
    await page.goto('/checkout/cart');

    await page.getByTestId('cart-remove-item').first().click();

    await expect(page.getByTestId('minicart-count')).toBeHidden();
  });
});

5. Visuelle Regressionstests für Tailwind

Tailwind CSS baut Layout aus vielen kleinen, kombinierten Utility-Klassen zusammen, statt aus wenigen semantischen Stylesheet-Regeln. Genau das macht Tailwind produktiv, aber auch fragil gegenüber stillen Fehlern: Eine falsch gesetzte Klasse, ein versehentlich entfernter flex-Container oder eine geänderte Purge-Konfiguration werfen keinen Fehler, keine Exception, keinen fehlschlagenden Test, das Layout bricht einfach lautlos. Ohne visuelle Regressionstests fällt so etwas oft erst auf, wenn ein Kunde einen Screenshot einer verschobenen Produktkachel schickt.

Playwrights eingebaute Screenshot-Assertion oder ein spezialisierter Dienst wie Percy löst dieses Problem, indem er für kritische Seiten, Produktdetailseite, Kategorieseite, Warenkorb-Drawer, Checkout-Schritte, Baseline-Screenshots über mehrere Breakpoints hinweg speichert und bei jedem Pull-Request pixelgenau vergleicht. Für eine belastbare Testing-Strategie im Hyvä-Theme gehört diese Schicht direkt über die funktionalen Playwright-Tests, mit denselben Testdaten und Fixtures, aber einem anderen Assertion-Typ: nicht "ist der Text sichtbar", sondern "sieht die Seite noch genauso aus wie vorher".

6. CSP-Regressionstests

Hyväs Content-Security-Policy blockiert standardmäßig jedes Inline-Skript ohne gültige Nonce und jeden Request an eine nicht freigegebene Domain. Die Projektregel, nach jedem <script>-Block $hyvaCsp->registerInlineScript() aufzurufen, ist einfach zu befolgen, aber genauso einfach zu vergessen, gerade wenn ein Entwickler unter Zeitdruck ein neues Alpine-Snippet in ein bestehendes Template einfügt. Das Tückische: Im Entwicklungsmodus mit CSP im Report-Only-Modus fällt ein fehlender Aufruf oft gar nicht auf, weil der Browser das Skript trotzdem ausführt und die Verletzung nur in der Konsole meldet. In Produktion mit erzwungener CSP scheitert dieselbe Stelle dann lautlos.

Eine Teststrategie für Hyvä-Themes muss deshalb aktiv nach CSP-Verletzungen suchen, statt sich auf zufälliges Auffallen zu verlassen. Playwright erlaubt es, über page.on('console', ...) jede Konsolenmeldung während eines kompletten Testlaufs mitzuschneiden und am Ende zu prüfen, dass keine Meldung den String "Content Security Policy" oder "Refused to execute inline script" enthält. Ergänzend prüft ein zweiter Check das gerenderte HTML auf vorhandene Nonce-Attribute an allen Inline-Skript-Tags, ein fehlendes Nonce ist ein zuverlässiges Signal, dass registerInlineScript() an dieser Stelle vergessen wurde, lange bevor ein Kunde eine kaputte Cookie-Consent-Funktion meldet.

7. Barrierefreiheit mit axe-core prüfen

Jede Änderung an einem Hyvä-Theme fasst zwangsläufig Markup und Semantik an, ein neues Alpine-Attribut, ein umgebautes div, ein fehlendes aria-label auf einem Icon-Button. Barrierefreiheit ist deshalb kein separates Audit am Projektende, sondern gehört als automatisierter Check direkt in die bestehende Playwright-Suite. axe-core scannt die gerenderte Seite auf WCAG-Verstöße, fehlende Kontraste, fehlende Formularlabels, falsche Heading-Hierarchien, und lässt sich über @axe-core/playwright direkt in jeden bestehenden E2E-Test einhängen, ohne ein separates Tool oder einen zweiten Testlauf zu benötigen.

Für eine konsequente Testing-Strategie im Hyvä-Theme lohnt es sich, den axe-core-Check nicht nur auf statischen Seiten, sondern gezielt nach Alpine-Interaktionen laufen zu lassen, zum Beispiel nachdem ein Modal geöffnet oder das Mini-Cart-Drawer sichtbar wurde. Gerade dynamisch eingeblendete Inhalte vergessen häufig role- und aria-*-Attribute, weil sie im ursprünglichen Markup unsichtbar waren und beim ersten manuellen Review schlicht übersehen wurden.


// File: tests/e2e/accessibility.spec.ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test.describe('Accessibility regression via axe-core', () => {
  test('category page has no WCAG violations after applying a filter', async ({ page }) => {
    await page.goto('/catalog/category/view/id/12');

    // Trigger the Alpine-driven layered navigation flow before scanning
    await page.getByTestId('filter-toggle').click();
    await page.getByTestId('filter-option-color-blue').click();
    await page.waitForLoadState('networkidle');

    const results = await new AxeBuilder({ page })
      .withTags(['wcag2a', 'wcag2aa'])
      .analyze();

    expect(results.violations).toEqual([]);
  });
});

8. CI-Pipeline-Aufbau

Die Reihenfolge der Stufen in der CI-Pipeline entscheidet über die Feedback-Geschwindigkeit einer Teststrategie für Hyvä-Themes. Der Grundsatz: Die günstigste Prüfung läuft zuerst und blockiert alle folgenden Stufen bei einem Fehler, damit teure Ressourcen nicht für einen Commit reserviert werden, der ohnehin schon an einem trivialen Typfehler scheitert. PHPStan läuft zuerst, dauert Sekunden und benötigt keine Datenbank. Danach folgt PHPUnit gegen die ViewModel- und Service-Schicht, ebenfalls ohne Browser, aber mit etwas mehr Laufzeit durch Fixtures und Mocks.

Erst danach folgt der Build-Schritt, Tailwind-Kompilierung und Static-Content-Deploy, gefolgt von der Playwright-E2E-Suite gegen eine vollständig deployte Instanz und abschließend die visuelle Regression, die ohnehin auf denselben gerenderten Seiten aufsetzt wie die E2E-Tests. Diese Reihenfolge, PHPStan, PHPUnit, Build, Playwright, visuelle Regression, stellt sicher, dass ein Entwickler bei einem einfachen Typfehler in unter einer Minute Feedback bekommt, statt zehn Minuten auf einen kompletten Browser-Testlauf zu warten.


# File: .github/workflows/hyva-theme-tests.yml
name: Hyva Theme Test Pipeline

on:
  pull_request:
    branches: [main]

jobs:
  static-analysis:
    name: PHPStan (level 5)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run PHPStan against ViewModels and Services
        run: bin/analyse app/code/Mironsoft/Testing --level=5

  unit-tests:
    name: PHPUnit
    needs: static-analysis
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run PHPUnit unit test suite
        run: bin/phpunit --testsuite unit

  build:
    name: Tailwind build and static content deploy
    needs: unit-tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Tailwind CSS for the theme
        run: bin/npm --prefix app/design/frontend/Mironsoft/default/web/tailwind run build
      - name: Deploy static content
        run: bin/magento setup:static-content:deploy de_DE -t Mironsoft/default -f

  e2e-playwright:
    name: Playwright E2E and accessibility
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Playwright suite including axe-core checks
        run: npx playwright test tests/e2e

  visual-regression:
    name: Visual regression screenshots
    needs: e2e-playwright
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Compare screenshots against baseline
        run: npx playwright test tests/visual --update-snapshots=false

9. Kosten-Nutzen: was wann testen

Nicht jede Testschicht muss bei jedem einzelnen Pull-Request laufen. Eine realistische Teststrategie für Hyvä-Themes unterscheidet zwischen Prüfungen, die in Sekunden laufen und daher immer aktiv sein sollten, und Prüfungen, die mehrere Minuten Rechenzeit und einen echten Browser-Cluster brauchen, dafür aber tiefere Sicherheit liefern. Die folgende Tabelle stellt gegenüber, was Unit-Tests und was E2E-Tests in einem Hyvä-Theme jeweils abdecken sollten, mit Blick auf Umfang, Geschwindigkeit, Tooling und das Fehlersignal, das sie liefern.

Dimension Unit-Tests (PHPUnit) E2E-Tests (Playwright)
Umfang ViewModel-Methoden, Berechnungen, Formatierung, Sichtbarkeitsflags Warenkorb, Checkout, Suche, Facetten-Navigation als kompletter Flow
Geschwindigkeit Sekunden, keine Datenbank, kein Browser Minuten, echter Browser, echtes Deployment
Tooling PHPUnit, Mock-Objekte, PHPStan als Vorstufe Playwright, axe-core, Screenshot-Vergleich
Fehlersignal Exakte Methode und Zeile, sofort reproduzierbar Kaputter Nutzerfluss, Layoutbruch, CSP-Verstoß im echten DOM

Für den produktiven Betrieb bedeutet das: PHPStan und PHPUnit laufen bei jedem einzelnen Pull-Request, weil sie in unter einer Minute Ergebnisse liefern und keine nennenswerten Kosten verursachen. Die vollständige Playwright-Suite inklusive visueller Regression und axe-core-Checks lohnt sich bei jedem Pull-Request nur für den betroffenen Bereich, gezielt auf geänderte Templates beschränkt, während der komplette Suite-Lauf über alle Flows und Breakpoints hinweg nachts oder vor einem Release läuft. Diese Staffelung hält die Feedback-Schleife für Entwickler kurz, ohne auf die tiefere Absicherung durch die vollständige Teststrategie für Hyvä-Themes zu verzichten.

10. Zusammenfassung

Eine tragfähige Teststrategie für Hyvä-Themes kombiniert mehrere Ebenen der Testpyramide: PHPUnit für ViewModel-Logik als schnelle Basis, PHPStan als noch schnelleres erstes Gate vor jedem Commit, Playwright für komplette E2E-Flows über Alpine.js-gesteuerte Interaktionen, visuelle Regressionstests für Tailwind-Layouts, dedizierte CSP-Regressionstests und axe-core für Barrierefreiheit. Keine dieser Ebenen ersetzt die andere, jede deckt Fehlerklassen ab, die die anderen blind lassen.

Der Schlüssel für den produktiven Betrieb liegt in der Staffelung: schnelle, günstige Prüfungen wie PHPStan und PHPUnit laufen bei jedem Pull-Request, teurere Playwright-Läufe mit visueller Regression und axe-core-Checks beschränken sich pro Pull-Request auf den geänderten Bereich, während der vollständige Suite-Lauf über alle Flows nachts oder vor einem Release stattfindet. So bleibt die Feedback-Schleife für Entwickler kurz, ohne die tiefere Absicherung zu verlieren.

Teststrategie für Hyvä-Themes, das Wichtigste auf einen Blick

Schnelle Basis

PHPUnit für ViewModels und PHPStan als erstes Gate laufen bei jedem Pull-Request in Sekunden.

E2E mit Playwright

Komplette Flows über Alpine.js-Interaktionen, gezielt auf geänderte Bereiche beschränkt.

Visuell & CSP

Visuelle Regression für Tailwind-Layouts, dedizierte Tests gegen CSP-Verstöße.

Barrierefreiheit

axe-core-Checks in der CI-Pipeline decken WCAG-Verstöße frühzeitig auf.

11. FAQ: Teststrategie für Hyvä-Themes

1Wo steht Hyvä-Testing in der Testpyramide?
PHPUnit als breite Basis, Playwright an der Spitze, PHPStan und visuelle/CSP-Tests dazwischen.
2Warum eignet sich PHPUnit für ViewModels?
ViewModels sind reine PHP-Logik ohne Template-Kopplung, isoliert instanziierbar und testbar.
3Warum reicht PHPStan allein nicht?
Es prüft nur statisch, kein Laufzeitverhalten im Browser oder echtes Nutzerverhalten.
4Was deckt Playwright zusätzlich ab?
Komplette Flows im echten Browser inklusive Alpine.js-Interaktionen und DOM-Rendering.
5Wie teste ich visuelle Regressionen?
Playwright-Screenshot-Vergleiche gegen eine gepflegte Baseline.
6Was ist ein CSP-Regressionstest?
Prüft im echten Browser, dass keine Inline-Skripte ohne registerInlineScript() existieren.
7Wie viel deckt axe-core ab?
Etwa 30 bis 40 Prozent aller WCAG-Kriterien automatisiert, der Rest bleibt manuell.
8Welche Tests laufen bei jedem Pull-Request?
PHPStan und PHPUnit, schnell und ohne nennenswerte Kosten.
9Wann läuft die volle Suite?
Nachts oder direkt vor einem Release, nicht bei jedem einzelnen Pull-Request.
10Übertragbar auf andere Theme-Bereiche?
Ja, dasselbe Muster passt unverändert auf Checkout, Produktseite oder jeden anderen Bereich.

Mironsoft

Hyvä-Entwicklung, Testautomatisierung und CI/CD-Pipelines

Braucht euer Hyvä-Theme eine belastbare Teststrategie?

Wir bauen die passende Teststrategie für euer Hyvä-Theme auf: PHPUnit für ViewModels, PHPStan als Gate, Playwright E2E für Alpine.js-Flows, visuelle Regression und CSP-Checks, sauber in eure CI-Pipeline integriert.

Test-Audit

Bestehende Teststrategie prüfen und Lücken in Pyramide und CI identifizieren

Playwright-Suite

E2E-Tests für Warenkorb, Checkout, Suche und Facetten inklusive axe-core

CI-Integration

PHPStan, PHPUnit, Playwright und visuelle Regression in eure Pipeline einbauen