laravel-tdd
PHPUnitおよびPestを用いたLaravelのテスト駆動開発をサポートし、ファクトリ・データベーステスト・フェイク・カバレッジ目標の設定まで対応します。
description の原文を見る
Test-driven development for Laravel with PHPUnit and Pest, factories, database testing, fakes, and coverage targets.
SKILL.md 本文
Laravel TDD ワークフロー
80%+ のカバレッジ (unit + feature) を伴う Laravel アプリケーションのテスト駆動開発。
いつ使うのか
- Laravel での新機能またはエンドポイント
- バグ修正またはリファクタリング
- Eloquent モデル、ポリシー、ジョブ、通知のテスト
- プロジェクトが PHPUnit に標準化されていない場合、新しいテストには Pest を優先する
仕組み
Red-Green-Refactor サイクル
- 失敗するテストを書く
- パスするための最小限の変更を実装する
- テストが緑のままリファクタリングする
テスト層
- Unit: 純粋な PHP クラス、値オブジェクト、サービス
- Feature: HTTP エンドポイント、認証、バリデーション、ポリシー
- Integration: データベース + キュー + 外部境界
カバレッジに応じて層を選択:
- 純粋なビジネスロジックとサービスには Unit テストを使用。
- HTTP、認証、バリデーション、レスポンス形式には Feature テストを使用。
- DB/キュー/外部サービスを一緒に検証する際には Integration テストを使用。
データベース戦略
- ほとんどの feature/integration テストには
RefreshDatabaseを使用 (テスト実行ごとに 1 回マイグレーションを実行し、サポートされている場合は各テストをトランザクションでラップ。メモリ内データベースはテストごとに再マイグレーション可能) - スキーマが既にマイグレーションされていて、テストごとのロールバックのみが必要な場合は
DatabaseTransactions - 各テストに対して完全なマイグレーション/フレッシュが必要でそのコストを負担できる場合は
DatabaseMigrations
データベースに触れるテストではデフォルトで RefreshDatabase を使用: トランザクションをサポートするデータベースの場合、テスト実行ごとに 1 回 (静的フラグを介して) マイグレーションを実行し、各テストをトランザクションでラップ。:memory: SQLite またはトランザクションなしの接続の場合、各テストの前にマイグレーションします。スキーマが既にマイグレーションされていて、テストごとのロールバックのみが必要な場合は DatabaseTransactions を使用。
テストフレームワークの選択
- 利用可能な場合、新しいテストではデフォルトで Pest を使用。
- プロジェクトが既に PHPUnit に標準化されているか、PHPUnit 固有のツールが必要な場合のみ PHPUnit を使用。
例
PHPUnit 例
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 テスト例 (HTTP 層)
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 例
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 テスト Pest 例 (HTTP 層)
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']);
});
ファクトリとステート
- テストデータにはファクトリを使用
- エッジケースにはステートを定義 (archived, admin, trial)
$user = User::factory()->state(['role' => 'admin'])->create();
データベーステスト
- クリーンな状態には
RefreshDatabaseを使用 - テストを分離されていて決定論的に保つ
- 手動クエリではなく
assertDatabaseHasを優先
永続性テスト例
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);
}
}
副作用用の Fake
- ジョブには
Bus::fake() - キューに入れられたジョブには
Queue::fake() - 通知には
Mail::fake()とNotification::fake() - ドメインイベントには
Event::fake()
use Illuminate\Support\Facades\Queue;
Queue::fake();
dispatch(new SendOrderConfirmation($order->id));
Queue::assertPushed(SendOrderConfirmation::class);
use Illuminate\Support\Facades\Notification;
Notification::fake();
$user->notify(new InvoiceReady($invoice));
Notification::assertSentTo($user, InvoiceReady::class);
認証テスト (Sanctum)
use Laravel\Sanctum\Sanctum;
Sanctum::actingAs($user);
$response = $this->getJson('/api/projects');
$response->assertOk();
HTTP と外部サービス
- 外部 API を分離するには
Http::fake()を使用 - 送信ペイロードを
Http::assertSent()で検証
カバレッジ目標
- Unit + feature テストで 80%+ のカバレッジを強制
- CI では
pcovまたはXDEBUG_MODE=coverageを使用
テストコマンド
php artisan testvendor/bin/phpunitvendor/bin/pest
テスト設定
- 高速テストのため
phpunit.xmlでDB_CONNECTION=sqliteとDB_DATABASE=:memory:を設定 - 開発/本番データに触れないようテスト用に別々の env を保つ
認可テスト
use Illuminate\Support\Facades\Gate;
$this->assertTrue(Gate::forUser($user)->allows('update', $project));
$this->assertFalse(Gate::forUser($otherUser)->allows('update', $project));
Inertia Feature テスト
Inertia.js を使用する際は、Inertia テストヘルパーでコンポーネント名と props を検証。
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')
);
}
}
生の JSON assertion ではなく assertInertia を優先して、Inertia レスポンスと互換性のあるテストを保つ。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- affaan-m
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/affaan-m/everything-claude-code / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。