Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Integration Tests vs. Unit Tests: wann welche sinnvoll sind

Integration Tests vs. Unit Tests: wann welche sinnvoll sind

~6 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Kapitel 92 endete mit einer offenen Frage: der Happy Path von AwardPointsOnOrderPlaced - eine echte Bestellung, ein echtes Produkt, eine echte gespeicherte Ledger-Zeile - lässt sich zwar theoretisch komplett mocken, aber der Aufwand steht in keinem Verhältnis zum Erkenntnisgewinn. Genau an dieser Grenze beginnt die Domäne der Integrationstests.

Zwei unterschiedliche Fragen

Ein Unit Test beantwortet: "Ist diese eine Entscheidungslogik korrekt, isoliert von allem drumherum?" Ein Integrationstest beantwortet eine andere Frage: "Spielen die echten Magento-Bausteine tatsächlich so zusammen, wie es die Konfiguration verspricht?" - lädt db_schema.xml wirklich die richtige Tabelle, feuert sales_order_place_after wirklich den registrierten Observer, persistiert das EAV-ResourceModel wirklich über alle fünf Attributtabellen hinweg? Diese Fragen kann kein Mock beantworten, weil ein Mock per Definition nie die echte Magento-Verdrahtung durchläuft.

Wo Magentos Integrationstests laufen

dev/tests/integration/ bootstrapt eine echte, separate Magento-Installation gegen eine eigene Test-Datenbank (konfiguriert in dev/tests/integration/etc/install-config-mysql.php.dist), mit echtem Object Manager, echten Plugins, echten Observern, echten db_schema.xml-Tabellen. Jeder Testfall läuft standardmäßig in einer Transaktion, die am Ende zurückgerollt wird - die Testdatenbank bleibt zwischen einzelnen Tests sauber, ohne manuelles Aufräumen.

// Ausschnitt, illustrativ: ein Integrationstest für die tatsächliche
// Datenbank-Persistenz aus Kapitel 6, statt die dort verwendete
// PointsLedgerRepositoryInterface komplett zu mocken.
namespace Mironsoft\Loyalty\Test\Integration\Model;

use Magento\TestFramework\Helper\Bootstrap;
use Mironsoft\Loyalty\Api\Data\PointsLedgerInterfaceFactory;
use Mironsoft\Loyalty\Api\PointsLedgerRepositoryInterface;
use PHPUnit\Framework\TestCase;

/**
 * @magentoDbIsolation enabled
 */
class PointsLedgerRepositoryTest extends TestCase
{
    public function testSaveAndGetByIdRoundTrip(): void
    {
        $objectManager = Bootstrap::getObjectManager();
        $repository = $objectManager->create(PointsLedgerRepositoryInterface::class);
        $ledgerFactory = $objectManager->create(PointsLedgerInterfaceFactory::class);

        $entry = $ledgerFactory->create();
        $entry->setCustomerId(1)->setPoints(100)->setType('earn')->setBalanceAfter(100);

        $saved = $repository->save($entry);
        $loaded = $repository->getById((int) $saved->getLedgerId());

        self::assertSame(100, $loaded->getPoints());
    }
}

Tipp: @magentoDbIsolation enabled ist genau die Annotation, die die automatische Transaktions-Rückrollung nach jedem Test aktiviert - ohne sie sammeln sich Test-Ledger-Einträge in der Test-Datenbank an.

Faustregel für dieses Modul

  • Unit Test: reine Entscheidungslogik ohne Framework-Beteiligung - PointsCalculator (Kapitel 91), die Guard Clauses eines Observers (Kapitel 92), die Reconciliation-Arithmetik in ExpirePoints (Kapitel 33).
  • Integrationstest: alles, dessen Korrektheit von echter Magento-Verdrahtung abhängt - PointsLedgerRepository gegen die echte Tabelle (Kapitel 6), LoyaltyTierBackend::beforeSave() als registriertes EAV-Backend-Model (Kapitel 26), ob sales_order_place_after tatsächlich AwardPointsOnOrderPlaced auslöst (Kapitel 30), die vollständige EAV-Persistenz eines Rewards über alle fünf Attributtabellen (Kapitel 11-12).
  • Beides zusammen: die Entscheidungslogik in einem Unit Test isoliert prüfen, die Verdrahtung in einem separaten, schlankeren Integrationstest - nie denselben Sachverhalt in beiden Testarten redundant nachbauen.

Achtung: Integrationstests sind um Größenordnungen langsamer als Unit Tests - ein vollständiges Bootstrapping der Testinstallation kostet spürbar Zeit, selbst bevor der eigentliche Testcode läuft. Wer versucht, PointsCalculator (Kapitel 91) als Integrationstest zu schreiben, statt als Unit Test, verlangsamt die Testsuite messbar, ohne einen einzigen zusätzlichen Fehlerfall abzudecken - die Klasse hat schlicht keine Framework-Abhängigkeit, die ein Integrationstest prüfen könnte.

Kapitel 94 baut auf dieser Unterscheidung auf und beantwortet die nächste Frage: wie viel von alldem überhaupt getestet werden muss.