Testing Templates
You have written a JSON Template and now you want to test it. FLAT comes with a Test Framework that makes it easy to execute your code with various input and error conditions.
Our Test Specimen
Let's write a simple template that outputs some information on the incoming request. (You have to register it in your swagger.yaml
, we assume it is stored as api/request-info.xml
).
Looks easy. Let's try it out:
The result is:
So far, so good. If you look closely, you will notice that the template is buggy. But we will bump into this when writing tests for it :)
Writing a Test
In FLAT, tests are written in <flat-test>
XML files. Those tests work like regular flows, but they provide specialized actions to make testing easy.
Usually, tests should run in the context of the FLAT app. Therefore, we recommend putting tests in a tests/
folder next to the swagger.yaml
:
A test usually comprises
the flow code under test
setup code to provide input/env data
Create tests/test-request-tpl.xml
:
The flat
cli has a test
command to run tests. It it easiest to run it from inside the FLAT app dir (where swagger.yaml
resides).
Great! But there's still room for improvement…
Refactor for Testing
In the test, we had to copy the template from our production code. This doesn't really make sense. Because, now we test an isolated copy. If we break the actual flow, the test will still pass.
There are a couple of options to go about this.
We could extract the template body into a file:
Now, in the test, we only repeat that action call:
Note, that we provide a different src
attribute, because the relative path to the template differs for the flow and the test file.
Another approach is to extract the template code into a sub flow. This can be called both by the path flow and the test:
This looks much better! We now test the real template call.
However, that call did not specify an out
variable. To catch that template output in the test, we use the content()
function:
JSON File Comparisons
But we can also make the assertion part of tests look better. For the beginning we were explicitly using json-stringify()
to turn $result
into a string. And even worse, that string had to be compared to a clunky, escaped JSON string.
The comparison parameter (2nd field of assertions) can also be an object with special flags. We can instruct assert
to read the comparison value from a file:
Now we can put the expected JSON string into the golden file tests/request-info.golden
:
We can still simplify that by using the json
comparison mode:
The json
mode ensures that both wanted and actual results are valid JSON. The comparison is independent of the JSON formatting. This allows us the have the golden file pretty printed:
This makes changes to the file easier during development. Especially your co-workers will thank you for a readable git diff.
Full Example
api/request-info.xml
:
tests/test-request-tpl.xml
:
tests/request-info.golden
:
Call test:
Adding More Tests
So far, we have only tested one specific input. Let's provide another test with different input data, such as a GET
request or one without the data
query parameter. This will reveal a serious bug in our code!
You can copy the test to another file for the GET
case. If you think those variants are closely related, you can also add more test code after the <assert>
in our tests/test-request-tpl.xml
like this:
tests/request-info2.golden
could look like this:
What happens, when you call the flat test
command now?
We get an execution error! Luckily the debug (-d [topic]
) is enabled, so we see:
📝 Exercise: Fix that bug in the template!
💡 Hint: The number one reason for invalid JSON syntax are commas.
After we have fixed the bug in the template, the test result should look like this:
💡 Hint: You can call flat test
with multiple files:
Using Other Compare Flags
You can use more compare flags for your tests.
The contains
flag can be used to test whether an expression result contains a given string:
This assertion tests whether the path
property of $request
contains the string "a/".
The pattern
flag can be used to test whether an expression result matches a given regular expression:
This assertion tests whether the method
property of $request
matches case-insensitively the string "post".
See also
Testing API Requests (cookbook)
Testing Upstream Requests (cookbook)
Testing (reference)
assert
(reference)
Last updated