name: ‘step-04a-subagent-api-failing’ description: ‘Subagent: Generate red-phase API test scaffolds (TDD red phase)’ subagent: true
This is an isolated subagent running in parallel with E2E red-phase test generation.
What you have from parent workflow:
use_pactjs_utils), Pact MCP mode (pact_mcp)use_pactjs_utils enabled and provider source accessible)If use_pactjs_utils is enabled: Also generate consumer contract tests alongside API tests. Use the loaded pactjs-utils fragments (pactjs-utils-overview, pactjs-utils-consumer-helpers, pactjs-utils-provider-verifier, pactjs-utils-request-filter, pact-consumer-di, pact-consumer-framework-setup) for patterns. When generating consumer tests, enforce one pact.addInteraction() per it() block (see pactjs-utils-consumer-helpers.md Example 6) — PactV4’s Rust FFI non-deterministically drops interactions if multiple are chained in one test. If pact_mcp is "mcp", use SmartBear MCP tools (Fetch Provider States, Generate Pact Tests) to inform test generation.
Your task: Generate API test scaffolds for the feature’s expected behavior. They stay in test.skip() until the developer activates them for the current task (TDD RED PHASE).
test.skip() until the developer activates themFrom the story acceptance criteria (Step 1 output), identify:
Example Acceptance Criteria:
Story: User Registration
- As a user, I can POST to /api/users/register with email and password
- System returns 201 Created with user object
- System returns 400 Bad Request if email already exists
- System returns 422 Unprocessable Entity if validation fails
For each API endpoint, create test file in tests/api/[feature].spec.ts:
Test Structure (ATDD - Red Phase):
import { test, expect } from '@playwright/test';
// If Playwright Utils enabled:
// import { apiRequest } from '@playwright-utils/api';
test.describe('[Story Name] API Tests (ATDD)', () => {
test.skip('[P0] should register new user successfully', async ({ request }) => {
// THIS TEST WILL FAIL - Endpoint not implemented yet
const response = await request.post('/api/users/register', {
data: {
email: 'newuser@example.com',
password: 'SecurePass123!',
},
});
// Expect 201 but will get 404 (endpoint doesn't exist)
expect(response.status()).toBe(201);
const user = await response.json();
expect(user).toMatchObject({
id: expect.any(Number),
email: 'newuser@example.com',
});
});
test.skip('[P1] should return 400 if email exists', async ({ request }) => {
// THIS TEST WILL FAIL - Endpoint not implemented yet
const response = await request.post('/api/users/register', {
data: {
email: 'existing@example.com',
password: 'SecurePass123!',
},
});
expect(response.status()).toBe(400);
const error = await response.json();
expect(error.message).toContain('Email already exists');
});
});
CRITICAL ATDD Requirements:
test.skip() to mark tests as red-phase scaffoldsapiRequest() helper if Playwright Utils enableduse_pactjs_utils Enabled)When generating Pact consumer contract tests in the ATDD red phase, provider scrutiny applies with TDD-specific rules. Apply the Seven-Point Scrutiny Checklist from contract-testing.md (Response shape, Status codes, Field names, Enum values, Required fields, Data types, Nested structures) for both existing and new endpoints.
If provider endpoint already exists (extending an existing API):
// Provider endpoint: comment and scrutiny evidence block documenting findings for each pointtest.skip() (so the whole test including executeTest is skipped), not just the callbackIf provider endpoint is new (TDD — endpoint not implemented yet):
// Provider endpoint: TODO — new endpoint, not yet implementedtest.skip() and use realistic expectations from the storyGraceful degradation when provider source is inaccessible:
pact_mcp is "mcp"): Use SmartBear MCP tools to fetch existing provider states and verified interactions as reference// Provider endpoint: TODO — provider source not accessible, verify manually and set provider_scrutiny: "pending" in output JSONProvider endpoint comments are MANDATORY even in red-phase tests — they document the intent.
Example: Red-phase Pact test with provider scrutiny:
// Provider endpoint: TODO — new endpoint, not yet implemented
/*
* Provider Scrutiny Evidence:
* - Handler: NEW — not yet implemented (TDD red phase)
* - Expected from acceptance criteria:
* - Endpoint: POST /api/v2/users/register
* - Status: 201 for success, 400 for duplicate email, 422 for validation error
* - Response: { id: number, email: string, createdAt: string }
*/
test.skip('[P0] should generate consumer contract for user registration', async () => {
await provider
.given('no users exist')
.uponReceiving('a request to register a new user')
.withRequest({
method: 'POST',
path: '/api/v2/users/register',
headers: { 'Content-Type': 'application/json' },
body: { email: 'newuser@example.com', password: 'SecurePass123!' },
})
.willRespondWith({
status: 201,
headers: { 'Content-Type': 'application/json' },
body: like({
id: integer(1),
email: string('newuser@example.com'),
createdAt: string('2025-01-15T10:00:00Z'),
}),
})
.executeTest(async (mockServer) => {
const result = await registerUser({ email: 'newuser@example.com', password: 'SecurePass123!' }, { baseUrl: mockServer.url });
expect(result.id).toEqual(expect.any(Number));
});
});
Why test.skip():
test.skip() documents this is intentional (TDD red phase)test.skip() to verify green phaseIdentify fixtures needed for API tests:
Do NOT create fixtures yet - just track what’s needed for aggregation step.
Write JSON to temp file: /tmp/tea-atdd-api-tests-{{timestamp}}.json
{
"success": true,
"subagent": "atdd-api-tests",
"tests": [
{
"file": "tests/api/user-registration.spec.ts",
"content": "[full TypeScript test file content with test.skip()]",
"description": "ATDD API test scaffolds for user registration (RED PHASE)",
"expected_to_fail": true,
"acceptance_criteria_covered": [
"User can register with email/password",
"System returns 201 on success",
"System returns 400 if email exists"
],
"priority_coverage": {
"P0": 1,
"P1": 2,
"P2": 0,
"P3": 0
}
}
],
"fixture_needs": ["userDataFactory"],
"knowledge_fragments_used": [
"api-request",
"data-factories",
"api-testing-patterns",
"pactjs-utils-consumer-helpers",
"pact-consumer-di"
],
"test_count": 3,
"tdd_phase": "RED",
"provider_scrutiny": "completed",
"summary": "Generated 3 red-phase API test scaffolds for user registration story"
}
On Error:
{
"success": false,
"subagent": "atdd-api-tests",
"error": "Error message describing what went wrong",
"partial_output": {
/* any tests generated before error */
}
}
Subagent completes when:
test.skip() (documented red-phase scaffolds)Subagent terminates here. Parent workflow will read output and proceed to aggregation.
// Provider endpoint: comment (if CDC enabled)