Laravel Tdd

affaan-m/ECC/docs/tr/skills/laravel-tdd

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775無授權條款275K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫4 天前更新

Test-driven development for Laravel with PHPUnit and Pest, factories, database testing, fakes, and coverage targets.

AI 產生的概覽

指導 Laravel 應用程式的測試驅動開發,涵蓋 PHPUnit 與 Pest、工廠、資料庫測試、假物件與覆蓋率目標。

功能
此技能為 Laravel 應用程式提供測試驅動開發工作流程,涵蓋紅-綠-重構循環、單元、功能與整合測試分層,以及 80% 以上的覆蓋率目標。它說明 RefreshDatabase、DatabaseTransactions 與 DatabaseMigrations 等資料庫測試策略,並解說如何使用工廠、狀態以及針對工作、佇列、郵件、通知與事件的假物件。它也包含 HTTP 端點、授權、Sanctum 驗證、外部 HTTP 呼叫與 Inertia 回應的範例測試,以及常用測試指令與 phpunit.xml 設定。
適用情境
適用於新增 Laravel 功能或端點、修正錯誤或重構現有程式碼時。也適合測試 Eloquent 模型、原則、工作與通知,以及在為新測試選擇 Pest 或 PHPUnit 時使用。
執行需求
需要一個已安裝 PHPUnit 或 Pest 的 Laravel 專案,覆蓋率報告可選用 pcov 或 XDEBUG_MODE=coverage。此技能不附帶指令碼,僅包含說明與程式碼範例。

Laravel TDD İş Akışı

80%+ kapsam (unit + feature) ile Laravel uygulamaları için test-driven development.

Ne Zaman Kullanılır

  • Laravel'de yeni özellikler veya endpoint'ler
  • Bug düzeltmeleri veya refactoring'ler
  • Eloquent model'leri, policy'leri, job'ları ve notification'ları test etme
  • Proje zaten PHPUnit'te standartlaşmamışsa yeni testler için Pest'i tercih edin

Nasıl Çalışır

Red-Green-Refactor Döngüsü

  1. Başarısız bir test yazın
  2. Geçmek için minimal değişiklik uygulayın
  3. Testleri yeşil tutarken refactor edin

Test Katmanları

  • Unit: saf PHP sınıfları, value object'leri, servisler
  • Feature: HTTP endpoint'leri, auth, validation, policy'ler
  • Integration: database + kuyruk + harici sınırlar

Kapsama göre katmanları seçin:

  • Saf iş mantığı ve servisler için Unit testleri kullanın.
  • HTTP, auth, validation ve yanıt şekli için Feature testleri kullanın.
  • DB/kuyruklar/harici servisleri birlikte doğrularken Integration testleri kullanın.

Database Stratejisi

  • Çoğu feature/integration testi için RefreshDatabase (test run'ı başına bir kez migration'ları çalıştırır, ardından desteklendiğinde her testi bir transaction'a sarar; in-memory veritabanları test başına yeniden migrate edebilir)
  • Şema zaten migrate edilmişse ve sadece test başına rollback'e ihtiyacınız varsa DatabaseTransactions
  • Her test için tam bir migrate/fresh'e ihtiyacınız varsa ve maliyetini karşılayabiliyorsanız DatabaseMigrations

Veritabanına dokunan testler için varsayılan olarak RefreshDatabase kullanın: transaction desteği olan veritabanları için, test run'ı başına bir kez (static bir bayrak aracılığıyla) migration'ları çalıştırır ve her testi bir transaction'a sarar; :memory: SQLite veya transaction'sız bağlantılar için her testten önce migrate eder. Şema zaten migrate edilmişse ve sadece test başına rollback'lere ihtiyacınız varsa DatabaseTransactions kullanın.

Test Framework Seçimi

  • Mevcut olduğunda yeni testler için varsayılan olarak Pest kullanın.
  • Proje zaten PHPUnit'te standartlaşmışsa veya PHPUnit'e özgü araçlar gerektiriyorsa sadece PHPUnit kullanın.

Örnekler

PHPUnit Örneği

php
use App\Models\User;use Illuminate\Foundation\Testing\RefreshDatabase;use Tests\TestCase;
final class ProjectControllerTest extends TestCase{    use RefreshDatabase;
    public function test_owner_can_create_project(): void    {        $user = User::factory()->create();
        $response = $this->actingAs($user)->postJson('/api/projects', [            'name' => 'New Project',        ]);
        $response->assertCreated();        $this->assertDatabaseHas('projects', ['name' => 'New Project']);    }}

Feature Test Örneği (HTTP Katmanı)

php
use App\Models\Project;use App\Models\User;use Illuminate\Foundation\Testing\RefreshDatabase;use Tests\TestCase;
final class ProjectIndexTest extends TestCase{    use RefreshDatabase;
    public function test_projects_index_returns_paginated_results(): void    {        $user = User::factory()->create();        Project::factory()->count(3)->for($user)->create();
        $response = $this->actingAs($user)->getJson('/api/projects');
        $response->assertOk();        $response->assertJsonStructure(['success', 'data', 'error', 'meta']);    }}

Pest Örneği

php
use App\Models\User;use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\actingAs;use function Pest\Laravel\assertDatabaseHas;
uses(RefreshDatabase::class);
test('owner can create project', function () {    $user = User::factory()->create();
    $response = actingAs($user)->postJson('/api/projects', [        'name' => 'New Project',    ]);
    $response->assertCreated();    assertDatabaseHas('projects', ['name' => 'New Project']);});

Feature Test Pest Örneği (HTTP Katmanı)

php
use App\Models\Project;use App\Models\User;use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\actingAs;
uses(RefreshDatabase::class);
test('projects index returns paginated results', function () {    $user = User::factory()->create();    Project::factory()->count(3)->for($user)->create();
    $response = actingAs($user)->getJson('/api/projects');
    $response->assertOk();    $response->assertJsonStructure(['success', 'data', 'error', 'meta']);});

Factory'ler ve State'ler

  • Test verileri için factory'leri kullanın
  • Uç durumlar için state'leri tanımlayın (archived, admin, trial)
php
$user = User::factory()->state(['role' => 'admin'])->create();

Database Testi

  • Temiz durum için RefreshDatabase kullanın
  • Testleri izole ve deterministik tutun
  • Manuel sorgular yerine assertDatabaseHas tercih edin

Persistence Test Örneği

php
use App\Models\Project;use Illuminate\Foundation\Testing\RefreshDatabase;use Tests\TestCase;
final class ProjectRepositoryTest extends TestCase{    use RefreshDatabase;
    public function test_project_can_be_retrieved_by_slug(): void    {        $project = Project::factory()->create(['slug' => 'alpha']);
        $found = Project::query()->where('slug', 'alpha')->firstOrFail();
        $this->assertSame($project->id, $found->id);    }}

Yan Etkiler için Fake'ler

  • Job'lar için Bus::fake()
  • Kuyruğa alınmış işler için Queue::fake()
  • Bildirimler için Mail::fake() ve Notification::fake()
  • Domain event'leri için Event::fake()
php
use Illuminate\Support\Facades\Queue;
Queue::fake();
dispatch(new SendOrderConfirmation($order->id));
Queue::assertPushed(SendOrderConfirmation::class);
php
use Illuminate\Support\Facades\Notification;
Notification::fake();
$user->notify(new InvoiceReady($invoice));
Notification::assertSentTo($user, InvoiceReady::class);

Auth Testi (Sanctum)

php
use Laravel\Sanctum\Sanctum;
Sanctum::actingAs($user);
$response = $this->getJson('/api/projects');$response->assertOk();

HTTP ve Harici Servisler

  • Harici API'leri izole etmek için Http::fake() kullanın
  • Giden payload'ları Http::assertSent() ile doğrulayın

Kapsam Hedefleri

  • Unit + feature testleri için 80%+ kapsam zorlayın
  • CI'da pcov veya XDEBUG_MODE=coverage kullanın

Test Komutları

  • php artisan test
  • vendor/bin/phpunit
  • vendor/bin/pest

Test Yapılandırması

  • Hızlı testler için phpunit.xml'de DB_CONNECTION=sqlite ve DB_DATABASE=:memory: ayarlayın
  • Dev/prod verilerine dokunmaktan kaçınmak için testler için ayrı env tutun

Yetkilendirme Testleri

php
use Illuminate\Support\Facades\Gate;
$this->assertTrue(Gate::forUser($user)->allows('update', $project));$this->assertFalse(Gate::forUser($otherUser)->allows('update', $project));

Inertia Feature Testleri

Inertia.js kullanırken, Inertia test yardımcıları ile component ismi ve prop'ları doğrulayın.

php
use App\Models\User;use Inertia\Testing\AssertableInertia;use Illuminate\Foundation\Testing\RefreshDatabase;use Tests\TestCase;
final class DashboardInertiaTest extends TestCase{    use RefreshDatabase;
    public function test_dashboard_inertia_props(): void    {        $user = User::factory()->create();
        $response = $this->actingAs($user)->get('/dashboard');
        $response->assertOk();        $response->assertInertia(fn (AssertableInertia $page) => $page            ->component('Dashboard')            ->where('user.id', $user->id)            ->has('projects')        );    }}

Testleri Inertia yanıtlarıyla uyumlu tutmak için ham JSON assertion'ları yerine assertInertia tercih edin.

來源與署名

來源:affaan-m/ECC位於docs/tr/skills/laravel-tdd提交ef648e0

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架