Skip to content

Functional testing ​

Functional testing asks the plainest question: for a valid request, does the endpoint do what it is supposed to? It is where every suite starts, and with ApiWorkbench it needs no code.

What to check, per method ​

MethodSendCheck
GET one itemA known id200; the id matches; key fields have the right values
GET a listNothing, or a filter200; it is a list; an item has the expected fields; a filter really filters
POSTA valid body201; the body echoes what you sent; a new id exists; often a Location header
PUT / PATCHNew values200; the changed fields changed; the others did not
DELETEAn existing id204 or 200; a following GET gets 404

Build one, step by step ​

Using GET /products/2 from the Shop API sample.

  1. Create the request: GET {{baseUrl}}/products/2. Send it once and read the response, so you know what a correct answer looks like.

  2. Open the Tests tab and select Add test. Choose Status equals and enter 200.

  3. Add JSON field equals, with the path id and the expected value 2.

  4. Add JSON field equals for inStock with the value true.

  5. Add Header contains, with the header Content-Type and the text json.

  6. Add Time below (ms) with 1000.

  7. Select Send and open the response's Tests tab. Five passes.

Now prove the tests can fail: change an expected value, send, read the message, and change it back.

The five test kinds ​

TestPasses whenExample
Status equalsThe status is that code. 2xx accepts any code in the 200s201, or 2xx
Body containsThe text appears anywhere in the body"status":"active"
JSON field equalsThe value at the path equals the expected textdata.items[0].id = 42
Header containsThe header exists and contains the text. Leave the text empty to check only that the header existsContent-Type contains json
Time below (ms)The response took less than that500

Details and edge cases are in Tests without code.

Be exact about the status

Prefer 201 to 2xx for a create. An API that answers 200 where it promised 201 has changed its contract, and a 2xx test would never tell you.

Checking more than one value ​

JSON field equals compares one value. For "every item in the list has a price above zero", or "the body matches this schema", use a short post-response script. The script cookbook has ready-made ones.

Lists and filters ​

For a list endpoint, check three things:

  • It is the right size, where that is known: total = 3.
  • An item has the right shape: items[0].name exists and is correct.
  • A filter changes the result: GET /products?category=books returns only books. Test the filtered request separately, with items[0].category = books and the smaller total.

Do not test the order of a list unless the API promises one.

Did it really happen? ​

A 201 says the API claims it created something. Confirm it:

  1. POST /orders, and capture orderId = body.id.
  2. GET /orders/{{orderId}}, and check it returns that order.

That pair is the smallest workflow test.

With a mock

A mock answers the POST and the GET independently; it does not store anything. Use it to build and check the tests, then run them against a real test environment to prove state.

Organising the suite ​

  • Group requests by feature: Auth, Catalog, Orders. Imported collections keep their folders; for a suite built by hand in ApiWorkbench 1.4.0, use one collection per feature or a name prefix such as Orders: place an order.
  • Name requests for what they prove: Get a product, List only books.
  • Put baseUrl and credentials in collection variables or an environment.
  • Run the whole collection from its ⋯ menu with Run collection. See Collection runner.

Common mistakes ​

  • Only checking the status. A 200 with the wrong data is still wrong.
  • Checking a value that changes, such as a timestamp or a generated id. Check that it exists instead, or capture it.
  • Depending on leftover data: "user 57 exists". Create what you need in the run.
  • Comparing a number as text with stray spaces. The expected value is compared exactly.

Next steps ​