Testing & Code Qualität
Meistern Sie Testing und Code Qualität in GEMVC. Lernen Sie PHPStan Level 9 (das höchste statische Analyse Level), PHPUnit und Pest Testing Frameworks. GEMVC ist eines der wenigen Frameworks, das PHPStan Level 9 unterstützt!
What You'll Learn
PHPStan Level 9
Statische Analyse und Typensicherheit
PHPUnit Testing
Unit und Integration Testing
Pest Testing
Moderne Testing Framework Alternative
Video Coming Soon...
Warum GEMVC besonders für Testing ist
GEMVC ist **eines der wenigen existierenden Frameworks, das PHPStan Level 9 unterstützt** – das höchste Level der statischen Analyse in PHP! Dies bedeutet, dass Sie typ sicheren, fehlerfreien Code mit der besten IDE Unterstützung schreiben und Fehler abfangen können, bevor sie die Produktion erreichen.
🎯 Warum andere Frameworks Level 9 nicht erreichen können:
- • **Laravel/Symfony:** Magische Methoden und dynamische Fassaden unterbrechen die statische Analyse
- • **Eloquent/Doctrine:** Komplexe ORMs machen die Typen Inferenz unmöglich
- • **Dynamische Eigenschaften:** Framework Magie besiegt die statische Analyse
**GEMVCs Vorteil:** Sauberes, explizites, typ sicheres Design von Grund auf!
- **PHPStan Level 9** - Statische Analyse fängt Fehler vor der Laufzeit ab
- **PHPUnit** - Industrie Standard Unit Testing Framework
- **Pest** - Modernes, elegantes Testing Framework Alternative
- **Automatische Konfiguration** - Alle Tools werden während
gemvc initkonfiguriert - **Vorkonfiguriert** - Sofort nach der Installation einsatzbereit
Installation während gemvc init
Wählen Sie Ihre Testing Tools
Während gemvc init werden Sie aufgefordert, Testing und Code Qualitäts Tools zu installieren:
# Projekt initialisieren
gemvc init
# Wenn Sie dazu aufgefordert werden:
# PHPStan installieren? (j/n): j ← DRINGEND EMPFOHLEN!
# Testing Framework installieren? (j/n): j
# Testing Framework wählen:
# 1) PHPUnit
# 2) Pest
# Wählen Sie: 1 oder 2
⚠️ Wichtig:
**PHPStan wird dringend empfohlen!** Es wird automatisch in Ihrem Projekt installiert und konfiguriert. Verwenden Sie es während der Entwicklung, um Typfehler abzufangen, bevor sie die Produktion erreichen.
Was installiert wird:
- ✓ PHPStan Level 9 (falls ausgewählt) - Vorkonfigurierte
phpstan.neon - ✓ PHPUnit oder Pest (falls ausgewählt) - Testing Framework mit Konfiguration
- ✓ OpenSwoole Stubs - Für korrekte Typenprüfung mit OpenSwoole
- ✓ Redis Stubs - Für Verbindungstypensicherheit
- ✓ Test Verzeichnisstruktur - Bereit für Ihre Tests
PHPStan Level 9 - Statische Analyse
Was ist PHPStan Level 9?
PHPStan Level 9 ist das **höchste Level der statischen Analyse** in PHP. Es führt die gründlichste Typenprüfung durch, die möglich ist, und fängt Fehler vor der Laufzeit ab.
PHPStan Level 9 fängt ab:
- ✓ Typfehler vor der Laufzeit
- ✓ Null Pointer Exceptions
- ✓ Undefinierte Methodenaufrufe
- ✓ Inkorrekten Array Zugriff
- ✓ Typen Konflikte
- ✓ Fehlende Rückgabe Typen
- ✓ Inkorrekten Eigenschafts Zugriff
- ✓ Und vieles mehr!
PHPStan ausführen
Nach der Installation führen Sie PHPStan aus, um Ihren Code zu überprüfen:
# PHPStan Analyse ausführen
vendor/bin/phpstan analyse
# Oder Composer Script verwenden (falls konfiguriert)
composer phpstan
# Mit Baseline (bestehende Fehler ignorieren)
vendor/bin/phpstan analyse --generate-baseline
❌ Ohne PHPStan (Bugs in Produktion):
<?php
public function getUser($id)
{
// ❌ Keine Type Hints
// ❌ Könnte null zurückgeben - wird Fehler verursachen!
return $this->selectById($id)->name;
}
// Laufzeitfehler: Versucht, auf Eigenschaft 'name' von null zuzugreifen
✅ Mit PHPStan Level 9 (Abgefangen während der Entwicklung):
<?php
public function getUser(int $id): ?UserModel
{
// ✅ Type Hints
$user = $this->selectById($id);
if (!$user) {
return null; // ✅ Null Fall behandeln
}
return $user; // ✅ Typ sicher!
}
// PHPStan stellt sicher, dass dies immer sicher ist
Vorteile von PHPStan Level 9:
- ✓ **Typensicherheit** - Fangen Sie Fehler ab, bevor sie passieren
- ✓ **Bessere IDE Unterstützung** - Vollständige Code Vervollständigung, Refactoring, Navigation
- ✓ **Sauberer Code** - Erzwingt explizite, lesbare Typen
- ✓ **Weniger Bugs** - Statische Analyse fängt Probleme frühzeitig ab
- ✓ **Team Konsistenz** - Jeder schreibt Code auf die gleiche Weise
- ✓ **Selbstdokumentierend** - Typen kommunizieren die Absicht klar
PHPStan Konfiguration
Automatische Konfiguration
Wenn Sie PHPStan während gemvc init installieren, wird automatisch eine phpstan.neon Konfigurationsdatei erstellt:
parameters:
level: 9 # Höchstes Level!
paths:
- app
excludePaths:
- app/vendor
checkMissingIterableValueType: true
checkGenericClassInNonGenericObjectType: true
checkUninitializedProperties: true
checkNullables: true
checkThisOnly: false
checkUnionTypes: true
checkExplicitMixedMissingReturn: true
Was enthalten ist:
- ✓ **Level 9** - Höchstes statisches Analyse Level
- ✓ **OpenSwoole Stubs** - Korrekte Typenprüfung für OpenSwoole
- ✓ **Redis Stubs** - Verbindungstypensicherheit
- ✓ **App Verzeichnis** - Analysiert Ihren Anwendungscode
- ✓ **Alle Checks aktiviert** - Maximale Typensicherheit
PHPUnit Testing
3632Industrie Standard Testing
3638
PHPUnit ist das beliebteste Testing Framework für PHP. GEMVC konfiguriert es automatisch, wenn Sie es während gemvc init auswählen.
PHPUnit Tests ausführen
# Alle Tests ausführen
vendor/bin/phpunit
# Spezifische Testdatei ausführen
vendor/bin/phpunit tests/UserTest.php
# Mit Coverage ausführen
vendor/bin/phpunit --coverage-html coverage/
# Oder Composer Script verwenden
composer test
<?php
namespace Tests;
use PHPUnit\Framework\TestCase;
use App\Model\UserModel;
use App\Table\UserTable;
class UserModelTest extends TestCase
{
public function testCreateUser(): void
{
$user = new UserModel();
$user->name = 'John Doe';
$user->email = 'john@example.com';
$user->setPassword('password123');
$result = $user->createModel();
$this->assertEquals(201, $result->response_code);
$this->assertEquals('created', $result->message);
$this->assertNotNull($user->id);
}
public function testSelectByEmail(): void
{
$userTable = new UserTable();
$user = $userTable->selectByEmail('john@example.com');
$this->assertInstanceOf(UserModel::class, $user);
$this->assertEquals('john@example.com', $user->email);
}
public function testDuplicateEmail(): void
{
$user1 = new UserModel();
$user1->name = 'User 1';
$user1->email = 'duplicate@example.com';
$user1->setPassword('pass123');
$user1->createModel();
$user2 = new UserModel();
$user2->name = 'User 2';
$user2->email = 'duplicate@example.com';
$user2->setPassword('pass123');
$result = $user2->createModel();
$this->assertEquals(422, $result->response_code);
$this->assertStringContainsString('already exists', $result->service_message);
}
}
PHPUnit Funktionen:
- ✓ **Unit Tests** - Testen Sie einzelne Methoden und Klassen
- ✓ **Integration Tests** - Testen Sie vollständige Workflows
- ✓ **Assertions** - Umfassende Assertions Bibliothek
- ✓ **Test Coverage** - Messen Sie die Code Coverage
- ✓ **Mocking** - Mocken Sie Abhängigkeiten für isoliertes Testing
Pest Testing
Modernes, elegantes Testing
Pest ist ein modernes Testing Framework, das auf PHPUnit aufbaut. Es bietet eine elegantere, lesbare Syntax, während alle PHPUnit Funktionen beibehalten werden.
Pest Tests ausführen
# Alle Tests ausführen
vendor/bin/pest
# Spezifische Testdatei ausführen
vendor/bin/pest tests/UserTest.php
# Mit Coverage ausführen
vendor/bin/pest --coverage
# Oder Composer Script verwenden
composer test
<?php
use App\Model\UserModel;
use App\Table\UserTable;
test('erstellt Benutzer erfolgreich', function () {
$user = new UserModel();
$user->name = 'John Doe';
$user->email = 'john@example.com';
$user->setPassword('password123');
$result = $user->createModel();
expect($result->response_code)->toBe(201)
->and($result->message)->toBe('created')
->and($user->id)->not->toBeNull();
});
test('wählt Benutzer per E Mail aus', function () {
$userTable = new UserTable();
$user = $userTable->selectByEmail('john@example.com');
expect($user)->toBeInstanceOf(UserModel::class)
->and($user->email)->toBe('john@example.com');
});
test('verhindert doppelte E Mail', function () {
$user1 = new UserModel();
$user1->name = 'User 1';
$user1->email = 'duplicate@example.com';
$user1->setPassword('pass123');
$user1->createModel();
$user2 = new UserModel();
$user2->name = 'User 2';
$user2->email = 'duplicate@example.com';
$user2->setPassword('pass123');
$result = $user2->createModel();
expect($result->response_code)->toBe(422)
->and($result->service_message)->toContain('already exists');
});
Pest Vorteile:
- ✓ **Elegante Syntax** - Lesbarer Testcode
- ✓ **Basiert auf PHPUnit** - Alle PHPUnit Funktionen verfügbar
- ✓ **Besseres DX** - Verbesserte Entwickler Erfahrung
- ✓ **Fluente Assertions** - Verknüpfbare Erwartungen
- ✓ **Modernes PHP** - Verwendet die neuesten PHP Funktionen
Testing Best Practices
So verwenden Sie Testing Tools
Befolgen Sie diese Best Practices für effektives Testing und Code Qualität:
💡 PHPStan während der Entwicklung verwenden
Führen Sie PHPStan regelmäßig während der Entwicklung aus, nicht nur vor Commits:
# PHPStan häufig ausführen
vendor/bin/phpstan analyse
# Fehler sofort beheben
# Keine Typfehler ansammeln
**Tipp:** Richten Sie einen Datei Wächter ein oder führen Sie PHPStan in Ihrer IDE aus, um Fehler beim Tippen abzufangen!
💡 Tests für kritische Pfade schreiben
Konzentrieren Sie sich auf das Testen der Geschäftslogik, API Endpunkte und kritischer Workflows. Testen Sie nicht den Framework Code – testen Sie Ihren Anwendungscode.
💡 Die 4-Schichten Architektur testen
Testen Sie jede Schicht angemessen:
- • **API Schicht** - Schema Validierung, Authentifizierung testen
- • **Controller Schicht** - Geschäftslogik Steuerung testen
- • **Model Schicht** - Daten Validierungen, Transformationen testen
- • **Table Schicht** - Datenbankabfragen testen (Test Datenbank verwenden!)
💡 Test Datenbank verwenden
Verwenden Sie immer eine separate Test Datenbank. Führen Sie niemals Tests gegen Produktionsdaten aus! Konfigurieren Sie die Test Datenbank in Ihrer phpunit.xml oder Pest.php.
💡 Tests vor Commits ausführen
Machen Sie es sich zur Gewohnheit, sowohl PHPStan als auch Ihre Test Suite vor dem Committen von Code auszuführen. Dies verhindert, dass fehlerhafter Code in das Repository gelangt.
Kompletter Testing Workflow
Hier ist ein vollständiges Beispiel, das zeigt, wie Sie PHPStan und PHPUnit/Pest zusammen verwenden:
Schritt 1: Code mit Type Hints schreiben
<?php
namespace App\Model;
use App\Table\ProductTable;
use Gemvc\Http\JsonResponse;
use Gemvc\Http\Response;
class ProductModel extends ProductTable
{
public int $id;
public string $name;
public float $price;
public function createModel(): JsonResponse
{
// Geschäftsvalidierung
if (empty($this->name)) {
return Response::unprocessableEntity('Name ist erforderlich');
}
if ($this->price <= 0) {
return Response::unprocessableEntity('Preis muss größer als 0 sein');
}
// Datenbank Operation
$this->insertSingleQuery();
if ($this->getError()) {
return Response::internalError($this->getError());
}
return Response::created($this, 1, 'Produkt erfolgreich erstellt');
}
}
Schritt 2: PHPStan ausführen
# Code Qualität prüfen
vendor/bin/phpstan analyse
# PHPStan wird überprüfen:
# ✓ Alle Type Hints sind korrekt
# ✓ Keine Null Pointer Exceptions
# ✓ Alle Rückgabe Typen stimmen überein
# ✓ Keine undefinierten Methodenaufrufe
Schritt 3: Tests schreiben
<?php
namespace Tests;
use PHPUnit\Framework\TestCase;
use App\Model\ProductModel;
class ProductModelTest extends TestCase
{
public function testCreateProductSuccess(): void
{
$product = new ProductModel();
$product->name = 'Laptop';
$product->price = 999.99;
$result = $product->createModel();
$this->assertEquals(201, $result->response_code);
$this->assertEquals('created', $result->message);
$this->assertNotNull($product->id);
}
public function testCreateProductWithoutName(): void
{
$product = new ProductModel();
$product->price = 999.99;
// name ist leer
$result = $product->createModel();
$this->assertEquals(422, $result->response_code);
$this->assertStringContainsString('Name ist erforderlich', $result->service_message);
}
public function testCreateProductWithInvalidPrice(): void
{
$product = new ProductModel();
$product->name = 'Laptop';
$product->price = -100; // Ungültiger Preis
$result = $product->createModel();
$this->assertEquals(422, $result->response_code);
$this->assertStringContainsString('Preis muss größer als 0 sein', $result->service_message);
}
}
Schritt 4: Tests ausführen
# Alle Tests ausführen
vendor/bin/phpunit
# Oder mit Pest
vendor/bin/pest
# Überprüfen Sie, ob alle Tests bestanden
# ✓ testCreateProductSuccess
# ✓ testCreateProductWithoutName
# ✓ testCreateProductWithInvalidPrice
Wichtige Hinweise
- **PHPStan wird dringend empfohlen:** GEMVC ist eines der wenigen Frameworks, das PHPStan Level 9 unterstützt. Verwenden Sie es während der Entwicklung, um Typfehler abzufangen, bevor sie die Produktion erreichen!
-
**Automatische Konfiguration:** Wenn Sie PHPStan oder Testing Frameworks während
gemvc initauswählen, werden diese automatisch installiert und konfiguriert. Keine manuelle Einrichtung erforderlich! - **Während der Entwicklung verwenden:** Warten Sie nicht bis zum Ende, um PHPStan auszuführen. Verwenden Sie es kontinuierlich während der Entwicklung, um Fehler beim Schreiben von Code abzufangen.
- **Test Datenbank:** Verwenden Sie immer eine separate Test Datenbank. Führen Sie niemals Tests gegen Produktionsdaten aus! Konfigurieren Sie sie in Ihrer Test Framework Konfigurationsdatei.
- **Level 9 Vorteil:** Die saubere Architektur von GEMVC ermöglicht PHPStan Level 9, was andere Frameworks aufgrund magischer Methoden und dynamischer Eigenschaften nicht erreichen können.
🧪 Testing & Qualität abgeschlossen!
Ausgezeichnet! Sie haben gelernt, wie Sie PHPStan Level 9, PHPUnit und Pest in GEMVC verwenden. Denken Sie daran: GEMVC ist eines der wenigen Frameworks, das PHPStan Level 9 unterstützt – verwenden Sie es während der Entwicklung, um typ sicheren, fehlerfreien Code zu schreiben!