Teaches API testing from zero: what functional API testing covers, how it differs from contract testing and load testing, and a decision table that picks one tool from observable project facts (language and build file, whether an OpenAPI or GraphQL schema exists, functional vs spec-conformance fuzzing vs stateful security fuzzing, whether non-engineers read the tests). Names the real options (Postman with newman, REST Assured, Karate, Tavern, Schemathesis, RESTler), gives install and first-run commands with what a passing run looks like, and the traps that bite first: asserting only on HTTP status, order-dependent tests sharing server state, and hardcoded environment URLs and secrets. Use when an HTTP API needs automated tests and no tool has been chosen, or when an inherited suite only checks status codes.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The default path (Postman + newman) stays in the SKILL.md spine. Below are the shortest paths to one passing test for the other functional options. Point the base URL at a locally running service or a staging instance, never production.
Add the dependency, pinned to the current io.rest-assured:rest-assured
release (rest-assured.io):
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>6.0.1</version>
<scope>test</scope>
</dependency>The usage guide recommends statically importing io.restassured.RestAssured.*,
io.restassured.matcher.RestAssuredMatchers.*, and org.hamcrest.Matchers.*,
and writing assertions as given() / when() / then() with statusCode(...)
plus a body(...) matcher
(rest-assured wiki):
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Test
public void returns_200_with_id() {
given()
.baseUri(System.getenv("API_BASE_URL"))
.when()
.get("/items/1")
.then()
.statusCode(200)
.body("id", equalTo(1));
}Success looks like: mvn test reports the test as passing. Verify it can
fail by asserting equalTo(2).
Add io.karatelabs:karate-junit5 as a test dependency, pinned to a release
listed on the repository, and write a .feature file. match is the
assertion keyword, and #number / #string are type placeholders so the test
does not bind to volatile values
(github.com/karatelabs/karate,
docs.karatelabs.io):
Feature: Items API
Scenario: Get an item
Given url baseUrl
And path 'items/1'
When method GET
Then status 200
And match response == { id: '#number', name: '#string' }Success looks like: mvn test passes and an HTML report appears under
target/karate-reports/.
Install, then write one YAML file (github.com/taverntesting/tavern):
pip install tavern[pytest]test_name: GET /items/1 returns 200 with expected id
stages:
- name: fetch item
request:
url: "{host}/items/1"
method: GET
response:
status_code: 200
json:
id: 1Run it with py.test test_items.tavern.yaml -v, or without pytest via
tavern-ci --stdout test_items.tavern.yaml
(tavern.readthedocs.io).
Success looks like: pytest reports 1 passed. Verify it can fail by
changing the expected id.
There is nothing to author. uvx runs it without installing; uv pip install
makes it permanent. Both forms and the schemathesis run <schema-url> command
are from the README
(github.com/schemathesis/schemathesis):
uvx schemathesis run https://your-api.example.com/openapi.json
# or: uv pip install schemathesis && schemathesis run <schema-url>Success looks like: a per-endpoint summary with no failures. A failure prints the generated request that broke conformance, so treat the first run as a discovery pass rather than a gate.
RESTler needs Python 3.12.8 and .NET 8.0, and runs as four stages: compile a grammar from the spec, test (a smoke pass measuring coverage), fuzz-lean (one pass per endpoint with default checkers), then fuzz (breadth-first deep exploration) (github.com/microsoft/restler-fuzzer). The setup cost is real, so reach for it only after a functional suite exists and the API is a genuine resource lifecycle.