api-test skill
ApiTestCaseを使用してAPI Platformエンドポイントの機能テストを記述し、CRUD、バリデーション、セキュリティ、およびマルチテナントの分離を検証します。
- GitHubスター
- 29
- ファイル
- 1
- 最終コミット
- 2026年10月22日
- ライセンス
- —
- 許可されたツール
- —
api-test skillは何をしますか
api-testはAgent Skillsです。 ApiTestCaseを使用してAPI Platformエンドポイントの機能テストを記述し、CRUD、バリデーション、セキュリティ、およびマルチテナントの分離を検証します。.
skillのSKILL.mdから生成された要約。
api-test skill について
API Platformエンドポイントの機能テストを記述することは、このSKILLを使用する開発者の主なタスクです。CRUD操作、データバリデーション、セキュリティプロトコル、およびマルチテナントの分離を検証するテストスイートの作成を自動化します。特定のAPIリソースをテストする必要がある場合、既存の機能テストを修正する場合、またはエンドポイントで見つかったバグを再現する場合に、エージェントはこのツールをロードする必要があります。
このSKILLはApiTestCaseを利用してSymfonyベースのアプリケーション向けのPHPコードを生成し、認証ヘッダーの設定やデータベースフィクスチャの管理といった複雑な要件を処理します。また、ApiTestAssertionsTraitやRefreshDatabaseを使用することで、Laravel環境への特化したサポートも提供します。Doctrine ORMまたはMongoDBのどちらを使用している場合でも、リソースの整合性と適切なスキーマ管理を確保するために、適切なディレクトリに構造化されたテストファイルを生成します。
エージェントができること
- 1CRUD操作の検証特定のリソースに対して、GET、POST、PATCH、DELETEリクエストが正しく動作することを確認するための機能テストを生成します。
- 2データ制約のバリデーション無効なデータが送信された際に、APIが422ステータスコードを返すかどうかを確認するテストを作成します。
- 3マルチテナントセキュリティの強制ユーザーが他の組織に属するリソースにアクセスしたり、変更したりできないことを確認するためのテストを開発します。
skill の SKILL.md から作成されています。すべてのユースケースは、その引用と照合されています。
api-test skillのインストール方法
各コマンドはskillフォルダをクライアントのskillsディレクトリにコピーします。読み込むには、クライアントを再起動するか新しいセッションを開始してください。プラグインにapi-test skillをインストールする
/plugin marketplace add api-platform/skillset /plugin install api-platform@api-platform-skillset
Claude Codeにapi-test skillをインストールする
~/.claude/skills/api-test/SKILL.md
$ npx degit api-platform/skillset/skills/api-test ~/.claude/skills/api-testClaude Code (project)にapi-test skillをインストールする
.claude/skills/api-test/SKILL.md
$ npx degit api-platform/skillset/skills/api-test .claude/skills/api-testCodexにapi-test skillをインストールする
~/.agents/skills/api-test/SKILL.md
$ npx degit api-platform/skillset/skills/api-test ~/.agents/skills/api-testGemini CLIにapi-test skillをインストールする
~/.gemini/skills/api-test/SKILL.md
$ npx degit api-platform/skillset/skills/api-test ~/.gemini/skills/api-testClaude.aiにapi-test skillをインストールする
npx degit api-platform/skillset/skills/api-test api-test && zip -r api-test.zip api-test # claude.ai → Customize → Skills → + → Create skill → Upload a skill → api-test.zip
SKILL.md
GitHubで表示Testing API Platform Endpoints
Use ApiPlatform\Symfony\Bundle\Test\ApiTestCase for functional API tests.
Base Test Class
Create a base class that handles database setup and authentication:
<?php
namespace App\Tests;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase as SymfonyApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
class ApiTestCase extends SymfonyApiTestCase
{
protected function setUp(): void
{
parent::setUp();
// Reset database state for each test
$manager = static::getContainer()->get('doctrine')->getManager();
// For MongoDB: drop and recreate
// For ORM: use fixtures or transactions
}
/**
* Creates an authenticated client with test fixtures.
*/
public function createLoggedInClient(): Client
{
$manager = static::getContainer()->get('doctrine')->getManager();
// Create user, token, and required fixtures
$user = new User();
// ... set up user
$manager->persist($user);
$manager->flush();
// Return client with auth headers
return static::createClient([], [
'headers' => ['x-api-key' => 'test_token'],
]);
}
}
Basic CRUD Tests
class OrderTest extends ApiTestCase
{
public function testGetCollection(): void
{
$client = $this->createLoggedInClient();
$client->request('GET', '/orders');
$this->assertResponseIsSuccessful();
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
}
public function testCreate(): void
{
$client = $this->createLoggedInClient();
$client->request('POST', '/orders', [
'headers' => ['Content-Type' => 'application/ld+json'],
'json' => ['name' => 'Test Order', 'total' => 99.99],
]);
$this->assertResponseStatusCodeSame(201);
$data = $client->getResponse()->toArray();
$this->assertSame('Test Order', $data['name']);
}
public function testUpdate(): void
{
$client = $this->createLoggedInClient();
// Create then update
$client->request('POST', '/orders', [
'headers' => ['Content-Type' => 'application/ld+json'],
'json' => ['name' => 'Original'],
]);
$order = $client->getResponse()->toArray();
$client->request('PATCH', '/orders/' . $order['id'], [
'headers' => ['Content-Type' => 'application/merge-patch+json'],
'json' => ['name' => 'Updated'],
]);
$this->assertResponseIsSuccessful();
$this->assertSame('Updated', $client->getResponse()->toArray()['name']);
}
public function testDelete(): void
{
$client = $this->createLoggedInClient();
// ... create resource first
$client->request('DELETE', '/orders/' . $id);
$this->assertResponseStatusCodeSame(204);
}
}
Testing Validation
public function testCreateWithInvalidData(): void
{
$client = $this->createLoggedInClient();
$client->request('POST', '/orders', [
'json' => ['email' => 'not-valid'],
]);
$this->assertResponseStatusCodeSame(422);
$this->assertJsonContains([
'violations' => [
['propertyPath' => 'email', 'message' => 'This value is not a valid email address.'],
],
]);
}
Testing Authentication
public function testRequiresAuthentication(): void
{
// No auth headers — use raw createClient
$client = static::createClient();
$client->request('GET', '/orders');
$this->assertResponseStatusCodeSame(401);
}
Multi-Tenant Isolation Tests
Test that users can only access their own resources:
public function testIsolationBetweenUsers(): void
{
$client1 = $this->createLoggedInClient(); // User 1, Org 1
$client2 = $this->createSecondUserClient(); // User 2, Org 2
// User 1 creates a resource
$client1->request('POST', '/accounts', [
'headers' => ['Content-Type' => 'application/ld+json'],
'json' => ['address' => 'user1@example.com', 'password' => 'Pass123!'],
]);
$account = $client1->getResponse()->toArray();
// User 2 cannot read it
$client2->request('GET', '/accounts/' . $account['id']);
$this->assertResponseStatusCodeSame(404);
// User 2 cannot update it
$client2->request('PATCH', '/accounts/' . $account['id'], [
'headers' => ['Content-Type' => 'application/merge-patch+json'],
'json' => ['isActive' => false],
]);
$this->assertResponseStatusCodeSame(404);
// User 2 cannot delete it
$client2->request('DELETE', '/accounts/' . $account['id']);
$this->assertResponseStatusCodeSame(404);
// Collections are isolated
$client2->request('GET', '/accounts');
$collection = $client2->getResponse()->toArray();
$ids = array_column($collection['member'], 'id');
$this->assertNotContains($account['id'], $ids);
}
Testing Filters
public function testFilterByStatus(): void
{
$client = $this->createLoggedInClient();
// ... create test data with different statuses
$client->request('GET', '/orders?isActive=true');
$this->assertResponseIsSuccessful();
$data = $client->getResponse()->toArray();
foreach ($data['member'] as $order) {
$this->assertTrue($order['isActive']);
}
}
Common Assertions
$this->assertResponseIsSuccessful();
$this->assertResponseStatusCodeSame(201);
$this->assertJsonContains(['name' => 'Expected']);
$this->assertMatchesResourceItemJsonSchema(Order::class);
$this->assertMatchesResourceCollectionJsonSchema(Order::class);
Resetting the Schema Between Tests (ORM)
For a clean database per test, drop and recreate the schema in setUp(). API
Platform's own suite uses an internal ApiPlatform\Tests\RecreateSchemaTrait —
that namespace is not autoloaded in your app, so copy the mechanism rather than
importing it:
use Doctrine\ORM\Tools\SchemaTool;
protected function setUp(): void
{
parent::setUp();
$manager = static::getContainer()->get('doctrine')->getManager();
$metadata = $manager->getMetadataFactory()->getAllMetadata();
$schemaTool = new SchemaTool($manager);
$schemaTool->dropDatabase();
$schemaTool->createSchema($metadata);
}
For MongoDB ODM, drop the collections via
$manager->getSchemaManager()->dropDocumentCollection(...) instead.
Test File Location
Place tests in tests/Functional/ following the naming convention {ResourceName}Test.php.
Laravel
Laravel uses its own HTTP test client (PHPUnit Tests\TestCase or Pest), not
ApiTestCase. API Platform ships ApiPlatform\Laravel\Test\ApiTestAssertionsTrait
(adds assertJsonContains(), assertArraySubset(), getIriFromResource()). Use
RefreshDatabase for isolation and model factories for fixtures (not Doctrine
SchemaTool/fixtures).
<?php
namespace Tests\Feature;
use ApiPlatform\Laravel\Test\ApiTestAssertionsTrait;
use App\Models\Book;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class BooksTest extends TestCase
{
use RefreshDatabase, ApiTestAssertionsTrait;
public function testCreate(): void
{
$response = $this->postJson('/api/books', ['isbn' => '0099740915', 'title' => 'X']);
$response->assertStatus(201);
$this->assertJsonContains(['title' => 'X'], $response->json());
$book = Book::factory()->create();
$this->getJson($this->getIriFromResource($book))->assertStatus(200);
}
}
Key deltas: request helpers are getJson/postJson/patchJson/deleteJson;
assertions are $response->assertStatus(...), $response->assertHeader(...),
$this->assertDatabaseMissing(...). assertJsonContains() takes the decoded body
($response->json()). Isolation/validation(422)/auth tests use the same status-code
assertions; auth uses Sanctum/actingAs(), not custom headers. Pest is the default
and wraps the same trait via uses(RefreshDatabase::class, ApiTestAssertionsTrait::class).
このスキルのファイル
1api-test skillに関する質問
Claude Codeにapi-test skillをインストールするには
npx degit api-platform/skillset/skills/api-test ~/.claude/skills/api-testを実行してください。Claude Codeは~/.claude/skills(すべてのプロジェクト)または.claude/skills(単一プロジェクト)からskillsを読み込み、説明がタスクに一致する場合にskillを使用します。
api-test skillはどのクライアントで使用できますか
Agent Skills形式を読み込むすべてのクライアントで使用できます: Claude Code、Codex、Gemini CLI、claude.ai(ZIPとしてアップロード)。skill内のスクリプトは、クライアントがコード実行を許可した場合にのみ実行されます。
このSKILLはLaravelのテストをサポートしていますか?
はい、ApiTestCaseの代わりにApiTestAssertionsTrait、RefreshDatabase、およびモデルファクトリを使用したLaravel向けのガイダンスを提供します。