Skip to content

Dictionaries

RESTest invents values to fit what the document says: a number within the limits it gives, a date for a date, a word as long as the document allows. It also reuses what the API has already returned. But some values cannot be invented. An API that searches owners by surname finds nothing for a surname made of random letters, and one that wants a product code of its own answers every invented one with a refusal. If you know values the API will accept, write them in a dictionary and hand it over. The format, with everything it can say, is The dictionary format.

Look at the summary of a run. If an operation keeps being refused — 4xx for nearly every request to it — and the reason is a value only somebody who knows the API could supply, a dictionary is the answer. Identifiers that exist, names the API holds, codes it recognises: those are what dictionaries are for.

The clinic searches its owners by surname, and when RESTest creates an owner it has to invent a telephone number made only of digits. A dictionary with surnames the clinic holds and a few telephone numbers, for the search and for the two requests that create and change an owner:

version: 1
name: clinic
description: Owners the clinic knows, and telephone numbers it accepts.
keyedBy: operationAndParameter
values:
listOwners:
lastName: [Franklin, Davis, Rodriquez, McTavish, Coleman]
addOwner:
body.lastName: [Franklin, Davis, Rodriquez, McTavish, Coleman]
body.telephone: ["6085551023", "6085551749", "6085553198"]
updateOwner:
body.lastName: [Franklin, Davis, Rodriquez, McTavish, Coleman]
body.telephone: ["6085551023", "6085551749", "6085553198"]

Save it as clinic.yaml and hand it over with --dictionary:

Terminal window
restest run http://localhost:9966/petclinic/v3/api-docs --budget 30s --dictionary clinic.yaml

--dictionary takes a file or a directory of them, and can be given more than once.

  • version is the version of the format, 1.
  • name is what the list is called. A plan can name a list to say which requests draw on it; the plan RESTest carries asks every list you hand over when it builds requests meant to be accepted.
  • keyedBy is always operationAndParameter: the keys under values are operations, and under each one, the places in its request.
  • values holds the lists, each under its operation and its place. lastName is the query parameter of the search; body.lastName is the property inside the body that creates or changes an owner. A list fills only the places it is written under, so the surnames are written three times. The format says how to name every place.

A list is one voice among several. For a request meant to be accepted, the plan RESTest carries asks every source that has an answer — the document's sample, an invented value, what the API has returned, your lists — and draws one of the answers, giving your lists 40 parts in 100. With the file above, about half the surnames the search sends are yours — 45 of 98 in one 30-second run; requests that push at the API or change one thing in an accepted request send others again. To have your values sent whenever a list has one, change the plan so that it asks your lists before the others: The dictionary format says how.

A file RESTest cannot read is said before the first request, again at the end of the summary, and in report.json, and the run carries on without it. A file it can read but parts of which can never be used — a parameter the document does not have, a misspelt operation — is said in one line as the run starts. Either way, look at the first lines of the run.

report.json lists every list the run held, its own included:

Terminal window
jq '.dictionaries' restest-out/report.json
{
"read": [
{
"name": "fuzzing",
"from": "the list of values to push with that is built into RESTest"
},
{
"name": "clinic",
"from": "clinic.yaml"
}
],
"refused": []
}

A file under read was read. Being read is not the same as being used — the plan decides which requests draw on which lists — but a file that was not read was certainly not used.

A dictionary is often written from the OpenAPI document, by a person or a program going through it operation by operation. Writing one of these from a specification has the five rules that keep such a file correct, and the format's JSON Schema checks its shape before a run, or holds a language model to it while it writes one.

The next chapter changes how the tool itself behaves.