ai-context-engineering-for-qa: Skill for Claude Code

.claude/skills/api-tests/SKILL.md

api-tests is a skill for Claude Code from vlad-ryzhkov/ai-context-engineering-for-qa. It costs 55 tokens per session (4,096 once invoked), scanned A, original, Unlicense.

A tool for generating API tests in Kotlin from specifications, using JUnit 5 and Allure. It follows the project's required files and testing conventions.

In plain words
What is it for?
Use it to create production-ready Kotlin tests for API requests and responses, with JUnit 5 assertions and Allure links.
Why use it?
It turns an API specification into tests while enforcing the project's request wrapper, assertion, reporting, and JSON-serialization rules.

Skill for Claude Code

Written for Claude Code: allowed-tools in frontmatter. Also seen: mentions CLAUDE.md.

This is vlad-ryzhkov/ai-context-engineering-for-qa's own configuration. It tells Claude Code how to work on ai-context-engineering-for-qa itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything ai-context-engineering-for-qa configures →

Reuse

Borrowing it

Nothing to install: this file belongs to vlad-ryzhkov/ai-context-engineering-for-qa. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/vlad-ryzhkov/ai-context-engineering-for-qa/main/.claude/skills/api-tests/SKILL.md
Clone the repo
git clone --depth 1 https://github.com/vlad-ryzhkov/ai-context-engineering-for-qa

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for api-tests

README.md
[![agentmods](https://agentmods.dev/badge/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests/github.svg)](https://agentmods.dev/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests)
Your own site
<a href="https://agentmods.dev/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests"><img src="https://agentmods.dev/badge/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for api-tests

Your own site · 80×15
<a href="https://agentmods.dev/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests"><img src="https://agentmods.dev/badge/skills/vlad-ryzhkov/ai-context-engineering-for-qa/api-tests.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 55 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 4,096 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00055 $0.04096
Opus 5.5 $0.00022 $0.01638
Sonnet 5.5 $0.00011 $0.00819
Haiku 4.5 $0.00006 $0.00410

Measured 1mo ago against content hash e434bd9a9d29, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

api-tests scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 1mo ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.claude/skills/api-tests/SKILL.md · 167 lines

How it starts

The opening of the file, as written. The whole thing — 167 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Main pipeline: /repo-scout → /api-test-cases → /api-tests.

For single-endpoint deep-dive: /spec-audit → /api-isolated-tests → /api-tests.

Running directly on a specification also works — the skill will generate tests without a scenario matrix, but traceability @Link annotations will reference the spec instead of scenario IDs.


🔒 SYSTEM REQUIREMENTS

Before execution the agent MUST load: .claude/protocols/gardener.md


SDET: API Automation (Kotlin)

When to Use

  • There is audit/test-scenarios.md with a scenario matrix — cover them with automated tests
  • Need to write tests for a new endpoint from scratch
  • Review existing tests for standards compliance (review arg)

Input Context (Process Isolation)

context: fork — you cannot see chat history before your invocation.

Allowed inputs: audit/test-scenarios.md, specification, CLAUDE.md, build.gradle.kts, existing src/ (style reference only). Forbidden: Assumptions from "previous agent context", inventing endpoint contracts.

Protocol

  1. Stack: Locked in CLAUDE.md → Tech Stack. Kotlin-specific additions: Ktor HttpClient(CIO) via by lazy(LazyThreadSafetyMode.SYNCHRONIZED), Awaitility (seconds only), Faker (TestData generators), JSON Schema Validator.
  2. BANNED: Thread.sleep, delay, runBlocking (use runTest), HttpClient( in *Tests.kt (inline HTTP in tests), manual @AllureId, shouldBe (use assertEquals), assert( (Kotlin builtin — use assertEquals/assertTrue from org.junit.jupiter.api.Assertions), LocalDateTime.now() in strict assertions. Zero-comment policy: // and /* */ in generated code are FORBIDDEN. 2a. Coroutine Tests: Preferred: fun test(): Unit = runTest { } from kotlinx-coroutines-test. If runBlocking is unavoidable — explicit return type required: fun test(): Unit = runBlocking { }. FORBIDDEN: delay() as timing substitute — use Awaitility. 2b. Test Lifecycle: @BeforeEach/@AfterEach for setup/teardown. lateinit var for resources requiring cleanup. FORBIDDEN: @TestInstance(PER_CLASS) with field initialization — JUnit skips class init on constructor failure. 2c. DRY API Clients: FORBIDDEN: duplicating client method bodies to return different response types (e.g., registerUser(): RegisterResponse + registerUserExpectError(): ErrorResponse with identical request construction). Generate a single method returning HttpResponse or a generic suspend inline fun <reified T> request(...) and let the test parse the body as needed. (ref: api/dry-api-client.md) 2d. Fail Fast in Test Clients: FORBIDDEN: wrapping API client HTTP calls or JSON deserialization in try/catch blocks that return empty stub objects (catch (e: Exception) { return RegisterResponse() }). Exceptions MUST propagate so the test runner reports the infrastructure failure at the point of failure, not on a later assertion. (ref: api/silent-catch.md) 2e. Ktor Body Extraction Rule: FORBIDDEN: response.toString() to obtain response body — in Ktor this returns object metadata, not the body. Use response.body<T>() (typed, via ContentNegotiation plugin) or response.bodyAsText() if raw string is required. Manual Json.decodeFromString(response.toString()) is a guaranteed runtime crash. (ref: api/ktor-body-extraction.md) 2f. Single Serialization Framework Rule: Use exactly one JSON framework across the entire generation — either Jackson OR kotlinx.serialization. FORBIDDEN: mixing Jackson annotations (@JsonProperty, @JsonNaming, @JsonIgnoreProperties) with kotlinx.serialization parsing (Json.decodeFromString, @Serializable). If using Ktor with ContentNegotiation(jackson()), deserialize via response.body<T>() — never parse raw strings manually. If the stack is jackson, all DTOs use @JsonNaming/@JsonProperty. If the stack is kotlinx.serialization, all DTOs use @Serializable and no Jackson annotations appear anywhere. 2g. Time-Dependent Scenarios (TTL/Cache): FORBIDDEN: Using Thread.sleep or delay() to simulate time passing for cache expiration, idempotency TTLs, or rate limits. Do not blindly execute sequential requests expecting time to advance instantly. For short asynchronous state changes, use Awaitility. For long temporal conditions (e.g., 5-minute cache expiration), if the specification does NOT explicitly provide a testability hook (e.g., X-Test-Advance-Time header or cache invalidation endpoint), you MUST generate the complete test logic and annotate the test method with @Disabled("Time-dependent scenario: {Wait Time}. Requires testability hook (time-travel/cache-clear) or manual execution."). 2h. Timestamp Response Validation: If the specification defines a time-based response field (e.g., expires_at = request_time + N minutes, JWT exp claim), the test MUST validate it with a relative drift check: assertTrue(abs(actual - expected) < driftToleranceSeconds, "timestamp drift"). Using Instant.now() + offset is acceptable; using isNotBlank() or > 0 alone is INSUFFICIENT. FORBIDDEN: LocalDateTime.now() in assertions. 2i. WireMock Integration for External Services: When a test configures WireMock stubs for external services (SMS gateway, payment provider, etc.), the test MUST connect the mock to the application under test. At minimum: set a system property or environment variable (e.g., System.setProperty("SMS_GATEWAY_URL", "http://localhost:${wireMockServer.port()}")) in @BeforeEach and clear it in @AfterEach. A disconnected WireMock server (started but not referenced by the app) is a SILENT TEST BUG — the test passes/fails based on real service state, not mock behavior. 2k. Eventual Consistency Writes: If repo-scout-report §12 marks a write→read pair as "Eventual", FORBIDDEN to assert the read immediately after write. Use Awaitility polling with bounded timeout. (ref: api/eventual-consistency-writes.md) 2l. Batch Partial Failure: If repo-scout-report §12 lists batch operations, include a mixed valid+invalid input case to verify error propagation strategy (atomic rollback vs partial 207 Multi-Status). Testing only all-valid and all-invalid is INSUFFICIENT. (ref: api/batch-partial-failure.md) 2j. Configurable BASE_URL: Use a computed property so any CI/CD environment can override the target server without recompilation: val BASE_URL: String get() = System.getProperty("BASE_URL", "http://localhost:8080"). If ConnectException appears in Smoke Run and no live server is available → run /api-mocks to generate an in-process mock, then re-run. TLS-enforcement tests cannot pass with an HTTP mock — acceptable as documented infra limitation. 2m. TLS/HTTPS Enforcement Tests: FORBIDDEN: generating a test that replaces https:// with http:// and asserts a 4xx rejection — when both URLs hit the same HTTP-only mock, the test structurally passes regardless of TLS state (silent false-positive). If a scenario requires verifying TLS enforcement and no HTTPS infrastructure exists: generate the test skeleton, immediately annotate @Disabled("TLS enforcement: requires HTTPS-capable server or WireMock HTTPS mode. HTTP mock cannot simulate certificate/protocol rejection."), and add a code comment explaining the correct infrastructure requirement. Do NOT generate a functionally broken test. 2n. HTTP Client Timeout (Mandatory): Every HttpClient instantiation MUST include: install(HttpTimeout) { requestTimeoutMillis = 30_000L; connectTimeoutMillis = 10_000L; socketTimeoutMillis = 30_000L }. Tests without timeout configuration hang indefinitely on infrastructure failures and block CI pipelines.
  3. Security Headers Rule: Every positive test (POST/PUT/DELETE with 2xx) MUST verify Content-Type, X-Content-Type-Options, Strict-Transport-Security via assertEquals on response.headers. (ref: api/missing-security-headers.md)
  4. Structure:
    • requests/: DTOs + Request/Response objects. ALL data classes mapped to snake_case JSON (request AND response) — apply @JsonNaming(SnakeCaseStrategy::class) on all DTOs — omitting it on response DTOs causes silent null fields. Also add @JsonIgnoreProperties(ignoreUnknown = true).
    • helpers/: @Step annotated flows.
    • tests/: @Epic (from feature/package name), @Feature (from endpoint name), @Severity, @DisplayName. @AllureId — NOT generated: assigned manually or via utility after TMS binding. MANDATORY TAGS: Analyze business logic — add @Tag("CRITICAL") + @Severity(SeverityLevel.CRITICAL) for Money flows, Security/Auth, or Data integrity endpoints; add @Tag("REGRESSION") for all others.
    • External Integrations: If the endpoint under test calls 3rd-party services (payments, SMS, email providers), configure a WireMock stub in @BeforeEach so the test does not make real HTTP calls to external domains.
  5. Gates: compileTestKotlin, ktlintCheck.

Read the full file on GitHub · 167 lines

Files

What ships with it

3 files beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 1mo ago Changed · +142 lines · +34 tokens per session e434bd9a9d29
  2. 1mo ago First seen · 25 lines · 21 tokens per session scan A 2d17a848602a

Subscribe to this mod's changes

api-tests is a skill published in the GitHub repository vlad-ryzhkov/ai-context-engineering-for-qa (6 stars, last pushed 1mo ago), licensed Unlicense. It adds 55 tokens to every session and 4,096 once invoked, about $0.0002 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

Kotlin Testing Patterns

Kotlin testing with JUnit 5, MockK, Kotest, coroutine testing, Android testing with Espresso, and Kotlin-specific assertion libraries.

PramodDutta/qaskills · 34 tokens

effective-kotlin

Apply Effective Kotlin best practices (Marcin Moskała, 2nd Ed). Covers Safety (Items 1-10: mutability, scope, nulls, types, expectations, errors, resources, tests), Readability (Items 11-18: operators, receivers, properties, naming), Reusability (Items 19-25: DRY, generics, delegation, variance), Abstraction (Items…

booklib-ai/booklib · 212 tokens

kotlin-in-action

Apply Kotlin In Action practices (Elizarov, Isakova, Aigner, Jemerov, 2nd Ed). Covers Basics (Ch 1-3: functions, extensions, default args), Classes (Ch 4: sealed, data, delegation, companion objects), Lambdas (Ch 5-6: functional APIs, sequences, scope functions), Nullability (Ch 7-8: safe calls, Elvis, platform types…

booklib-ai/booklib · 250 tokens

exploratory-nightly-verification

Operational rules for a 60-minute single-shot exploratory verification of a Kotlin project's main branch (Android / JVM / KMP / Compose / server-side Kotlin). Runs sequentially through cat1–cat5 inside a single CI job (e.g. a nightly GitHub Actions workflow), writes findings Markdown-by-Markdown to…

TBSten/skills · 186 tokens

kotlin-testing

Kotlin testing patterns with Kotest, MockK, coroutine testing, property-based testing, and Kover coverage. Follows TDD methodology with idiomatic Kotlin practices.

affaan-m/ECC · 38 tokens

swift-testing-pro

Writes, reviews, and improves Swift Testing code using modern APIs and best practices. Use when reading, writing, or reviewing projects that use Swift Testing.

jacklandrin/OnlySwitch · 34 tokens