Skip to content

TestRunCommand - Intelligenter Test-Runner mit automatischem Setup

Übersicht

Der TestRunCommand ist ein neuer Artisan-Command, der Test-Ausführung und Datenbank-Setup intelligent kombiniert. Er prüft automatisch, ob die Test-Datenbank bereit ist und führt nur bei Bedarf ein Setup durch.

Hauptfeatures:

  • Smart-Check-Logik: Setup nur wenn wirklich nötig
  • Automatische Datenbank-Validierung
  • Integration mit allen Pest-Test-Optionen
  • Parallele Test-Ausführung
  • Detaillierte Status-Ausgaben

Verwendung

Basis-Syntax

bash
php artisan test:run [options]

Verfügbare Optionen

OptionBeschreibung
--freshDatenbank immer neu aufbauen (keine Smart-Checks)
--parallelTests parallel ausführen
--filter=NAMENur Tests ausführen die dem Filter entsprechen
--testsuite=NAMENur bestimmte Testsuite ausführen (Unit, Feature, Modules)
--coverageCode Coverage Report generieren
--stop-on-failureBei erstem Fehler abbrechen
--connection=NAMEDatenbank-Connection (Default: testing_local)

Beispiele

bash
# Standard: Smart-Check + parallele Tests
php artisan test:run --parallel

# Immer frisches Setup erzwingen
php artisan test:run --fresh --parallel

# Nur Unit-Tests
php artisan test:run --testsuite=Unit

# Nur spezifische Tests
php artisan test:run --filter="UebungBedeutungenZuordnen" --parallel

# Mit Coverage-Report
php artisan test:run --coverage

# Debugging: Bei erstem Fehler stoppen
php artisan test:run --stop-on-failure --no-parallel

Smart-Check-Logik

Der Command führt vier intelligente Checks durch, bevor er entscheidet ob ein Setup nötig ist:

1. Datenbank existiert?

php
private function databaseExists(): bool

Prüft:

  • Verbindung zur MySQL-Instanz
  • Existenz der konfigurierten Test-Datenbank

Ergebnis bei Fehler:

Setup erforderlich: Datenbank existiert nicht

2. Schema aktuell?

php
private function schemaIsUpToDate(): bool

Prüft:

  • migrations Tabelle existiert
  • Keine ausstehenden Migrationen (Vergleich Dateien vs. DB)

Ergebnis bei Fehler:

Setup erforderlich: Schema nicht aktuell (ausstehende Migrationen)

3. Base-Data vorhanden?

php
private function baseDataExists(): bool

Prüft (Stichprobe):

  • Mindestens 100 Einträge in glossarium_verben
  • Mindestens 20 Einträge in reihen

Ergebnis bei Fehler:

Setup erforderlich: Base-Data fehlt

4. Test-Accounts existieren?

php
private function testAccountsExist(): bool

Prüft:

  • Alle 5 Test-User existieren in users Tabelle:
    • bruce.wayne (admin)
    • harvey.dent (editor)
    • james.gordon (tester)
    • selina.kyle (teacher)
    • joker (user)

Ergebnis bei Fehler:

Setup erforderlich: Test-Accounts fehlen

Erfolgreiche Validierung

Wenn alle Checks erfolgreich sind:

Datenbank ist bereit (Setup nicht erforderlich).

Workflow-Ablauf

1. Initialisierung

=== Hermeneus Test Runner ===

Pruefe Datenbank-Status...

2. Smart-Check oder Fresh-Mode

Mit --fresh Flag:

--fresh Flag gesetzt: Datenbank wird neu aufgebaut.
Setup erforderlich: Fresh-Flag

Ohne --fresh (Smart-Check):

  • Führt alle 4 Checks durch
  • Gibt konkreten Grund aus wenn Setup nötig

3. Setup (falls erforderlich)

Setup erforderlich: [Grund]

[Output von test:setup Command]

Setup abgeschlossen.

Intern ruft der Command auf:

php
$this->call('test:setup', [
    '--fresh' => true,
    '--connection' => $this->connection,
]);

4. Test-Ausführung

=== Starte Tests ===

[Pest Test Output]

Intern ruft der Command auf:

php
$this->call('test', $arguments);

5. Zusammenfassung

Gesamtdauer: 2 minutes

Integration mit NPM Scripts

Die NPM-Scripts in package.json nutzen den TestRunCommand:

json
{
  "scripts": {
    "test": "php artisan test:run --parallel",
    "test:fresh": "php artisan test:run --parallel --fresh",
    "test:setup": "php artisan test:setup --fresh",
    "test:unit": "php artisan test:run --testsuite=Unit",
    "test:feature": "php artisan test:run --testsuite=Feature",
    "test:modules": "php artisan test:run --testsuite=Modules --parallel",
    "test:filter": "php artisan test:run --parallel --filter",
    "test:no-parallel": "php artisan test:run"
  }
}

Verwendung:

bash
# Entwickler-freundlich: Einfach npm run test
npm run test

# Automatisches Setup wenn nötig
npm run test:fresh

# Spezifische Suite
npm run test:unit

Vorteile gegenüber direktem php artisan test

Featurephp artisan testphp artisan test:run
Automatisches SetupNeinJa (Smart-Check)
Datenbank-ValidierungNeinJa (4 Checks)
Setup nur wenn nötigN/AJa
Frisches Setup erzwingenNeinJa (--fresh)
Test-OptionenJaJa (durchgereicht)
ZeiterfassungNeinJa (Gesamtdauer)
Fehler-HandlingBasicErweitert

Technische Details

Klasse und Namespace

php
namespace App\Console\Commands;

class TestRunCommand extends Command
{
    use DatabaseSetupActions;
}

Trait: DatabaseSetupActions wird von TestSetupCommand geteilt und bietet:

  • switchToConnection(string $connection)
  • Gemeinsame Datenbank-Helper-Methoden

Signature

php
protected $signature = 'test:run
    {--fresh : Datenbank immer neu aufbauen (keine Smart-Checks)}
    {--parallel : Tests parallel ausfuehren}
    {--filter= : Nur Tests ausfuehren die dem Filter entsprechen}
    {--testsuite= : Nur bestimmte Testsuite ausfuehren}
    {--coverage : Code Coverage Report generieren}
    {--stop-on-failure : Bei erstem Fehler abbrechen}
    {--connection=testing_local : Datenbank-Connection}';

Hauptmethode

php
public function handle(): int
{
    // 1. Initialisierung
    $startTime = now();
    $this->connection = $this->option('connection');
    $this->dbConfig = config("database.connections.{$this->connection}");

    // 2. Setup-Status prüfen
    if ($this->option('fresh')) {
        $setupRequired = true;
        $reason = 'Fresh-Flag';
    } else {
        [$setupRequired, $reason] = $this->checkSetupRequired();
    }

    // 3. Setup ausführen wenn nötig
    if ($setupRequired) {
        $setupResult = $this->runSetup();
        if ($setupResult !== Command::SUCCESS) {
            return Command::FAILURE;
        }
    }

    // 4. Tests ausführen
    $testResult = $this->runTests();

    // 5. Zusammenfassung
    $duration = $startTime->diffForHumans(now(), true);
    $this->line("Gesamtdauer: {$duration}");

    return $testResult;
}

Fehlerbehandlung

Datenbank-Verbindung fehlgeschlagen

php
catch (PDOException $e) {
    $this->warn("  DB-Verbindung fehlgeschlagen: " . $e->getMessage());
    return false;
}

Folge: Setup wird durchgeführt

Setup fehlgeschlagen

php
if ($setupResult !== Command::SUCCESS) {
    $this->error('Setup fehlgeschlagen! Tests werden nicht ausgefuehrt.');
    return Command::FAILURE;
}

Folge: Tests werden NICHT ausgeführt, Exit Code 1

Tests fehlgeschlagen

php
$testResult = $this->runTests();
return $testResult; // Exit Code von `php artisan test`

Folge: Exit Code wird durchgereicht (z.B. 1 bei Fehlern)

Best Practices

Entwicklungs-Workflow

  1. Erstmaliges Setup:

    bash
    npm run test:setup
  2. Reguläre Entwicklung:

    bash
    npm run test

    Smart-Check stellt sicher, dass Setup nur läuft wenn nötig

  3. Nach Schema-Änderungen:

    bash
    npm run test:fresh

    Erzwingt Neuerstellung der Datenbank

  4. Debugging einzelner Tests:

    bash
    npm run test:filter -- "Test-Name"
    # oder
    php artisan test:run --filter="Test-Name" --stop-on-failure

CI/CD Integration

Für CI-Pipelines empfiehlt sich immer --fresh:

yaml
# .github/workflows/tests.yml
- name: Run Tests
  run: npm run test:fresh

Grund: Garantiert sauberen Zustand, vermeidet Cache-Probleme

Lokale Performance-Optimierung

Für schnelle Test-Iterationen ohne Setup:

bash
# Einmal Setup
npm run test:setup

# Danach: Nur Tests ohne Setup
php artisan test --parallel

Nur verwenden wenn:

  • Keine Schema-Änderungen
  • Keine Base-Data-Änderungen
  • Sichere Datenbank-Konsistenz

Verwandte Commands

CommandZweck
test:setupNur Setup ohne Tests
test:runSetup (smart) + Tests
testNur Tests (kein Setup)

Troubleshooting

"DB-Verbindung fehlgeschlagen"

Ursache: MySQL-Server läuft nicht oder Credentials falsch

Lösung:

  1. MySQL-Server starten
  2. .env prüfen: DB_TEST_* Variablen
  3. Connection in config/database.php prüfen

"Setup fehlgeschlagen! Tests werden nicht ausgeführt."

Ursache: test:setup Command hat einen Fehler zurückgegeben

Lösung:

  1. Setup manuell ausführen: php artisan test:setup --fresh
  2. Log-Output analysieren
  3. Migrationen prüfen
  4. Base-Data SQL-Dateien prüfen

Tests laufen, obwohl Datenbank veraltet ist

Ursache: Smart-Checks greifen nicht (z.B. nur 1 Migration fehlt)

Lösung:

bash
npm run test:fresh

Setup läuft bei jedem Test-Lauf

Ursache: Einer der 4 Checks schlägt immer fehl

Debugging:

  1. Command mit Ausgabe prüfen:

    bash
    php artisan test:run
    # Zeigt: "Setup erforderlich: [Grund]"
  2. Konkreten Check debuggen:

    php
    // In TestRunCommand.php
    dd($this->databaseExists());
    dd($this->schemaIsUpToDate());
    dd($this->baseDataExists());
    dd($this->testAccountsExist());

Weiterführende Dokumentation