Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when writing API endpoint tests — integration tests, contract validation, response assertions, mocked external services — even when the user says 'test this route' without naming API testing.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Use this skill when writing or reviewing API endpoint tests — integration tests, contract validation, response structure checks, or external service mocking.
Http::fake().test-case-discovery funnel first; cover success, validation errors, authorization failures, and edge cases — floor per behavior: 1 happy + 1 boundary + 1 error (+1 abuse case; on data-returning endpoints the three broken-access-control negative tests are mandatory).assertJsonStructure().describe('GET /api/v1/projects', function () {
it('returns paginated projects for authenticated user', function () {
$user = loginAsTestUser();
$response = $this->getJson('/api/v1/projects');
$response->assertOk()
->assertJsonStructure([
'data' => [['id', 'title', 'status']],
'meta' => ['current_page', 'per_page', 'total'],
]);
});
it('returns 401 for unauthenticated request', function () {
$this->getJson('/api/v1/projects')
->assertUnauthorized();
});
it('returns 403 when user lacks permission', function () {
loginAsRestrictedUser();
$this->getJson('/api/v1/projects')
->assertForbidden();
});
});
Test the expected success scenario with valid input:
it('creates a project', function () {
loginAsTestUser();
$this->postJson('/api/v1/projects', [
'title' => 'New Project',
'customer_id' => $customerId,
])
->assertCreated()
->assertJsonPath('data.title', 'New Project');
$this->assertDatabaseHas('projects', ['title' => 'New Project']);
});
Test that invalid input is rejected with correct error messages:
it('rejects project without title', function () {
loginAsTestUser();
$this->postJson('/api/v1/projects', [
'customer_id' => $customerId,
])
->assertUnprocessable()
->assertJsonValidationErrors(['title']);
});
Test that unauthorized access is blocked:
it('prevents non-owner from updating project', function () {
$otherUser = loginAsOtherUser();
$this->putJson("/api/v1/projects/{$project->id}", [
'title' => 'Hijacked',
])
->assertForbidden();
});
Test boundary conditions:
it('handles empty collection', function () {
loginAsTestUser();
$this->getJson('/api/v1/projects')
->assertOk()
->assertJsonCount(0, 'data');
});
it('paginates large result sets', function () {
loginAsTestUser();
$this->getJson('/api/v1/projects?per_page=5')
->assertOk()
->assertJsonPath('meta.per_page', 5);
});
// Verify response shape (keys exist)
$response->assertJsonStructure([
'data' => ['id', 'title', 'status', 'created_at'],
]);
// Verify exact values
$response->assertJsonPath('data.status', 'active');
// Verify collection count
$response->assertJsonCount(3, 'data');
// When strict typing matters
$data = $response->json('data');
expect($data['id'])->toBeInt();
expect($data['title'])->toBeString();
expect($data['total'])->toBeString(); // Money as string, not float
When a failing test dumps the full JSON body, narrow the diagnosis with jq or grep
instead of scrolling the whole payload:
# Extract only the failing assertion path
echo "$RESPONSE_JSON" | jq '.data.status, .errors'
# Targeted log scan
rg --json 'API call failed' storage/logs/laravel.log | jq -r '.data.lines.text'
it('handles external API failure gracefully', function () {
Http::fake([
'external-api.com/*' => Http::response(null, 500),
]);
loginAsTestUser();
$this->postJson('/api/v1/sync')
->assertStatus(502)
->assertJsonPath('message', 'External service unavailable');
});
| Category | Tests needed |
|---|---|
| Auth | Unauthenticated (401), unauthorized (403) |
| Validation | Missing fields, wrong types, boundary values |
| Happy path | Success with valid input, correct status code |
| Response | JSON structure, field types, pagination meta |
| Side effects | Database changes, events dispatched, jobs queued |
| Edge cases | Empty results, large payloads, concurrent access |
API tests cover the contract layer. When an endpoint feeds a UI surface (Livewire component, Blade-rendered page, SPA route), complement the API test with a thin UI probe: a livewire test for wired components, or a Playwright spec / browser screenshot for the rendered shell. Never assume the UI works just because the API test is green.
Http::fake() — never hit real services in tests.Http::fake() without also testing the real integration path.When a test fails, do not retry blindly with tweaked assertions until something passes. Diagnose the root cause first: print the actual response shape once, compare it to the contract, then write a targeted fix. Trial-and-error retries hide real regressions.
If the endpoint contract is ambiguous (unclear status code, optional fields, error envelope shape), do not assume. Ask the user or check the OpenAPI spec / route definition before writing assertions — never guess the response shape from the route name.
The examples above are Laravel's. The shape they teach — assert the status,
then the body contract, then the side effect, and keep one behavior per test —
transfers unchanged; the API does not. Resolve the runner with
resolve_toolchain and read its ecosystems:
ecosystems | Request + assertion surface |
|---|---|
php | $this->getJson(...) / assertStatus / assertJsonPath |
js | supertest or the framework's own test client, with expect(res.status) |
python | httpx.AsyncClient / framework TestClient; assert res.status_code |
go | httptest.NewServer + net/http, or the router's own ServeHTTP |
Whatever the surface, the negative tests are not optional: unauthenticated,
not-owner and cross-tenant each get their own case, per broken-access-control.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.
日本語の概要は準備中です。原文の説明を表示しています。
Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.
日本語の概要は準備中です。原文の説明を表示しています。
Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.
日本語の概要は準備中です。原文の説明を表示しています。
Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.
日本語の概要は準備中です。原文の説明を表示しています。