Flows
Create a Ply flow
- Launch VS Code, and in its Activity Bar click the Ply icon:
- Drop down Ply’s meatball menu:
- Name the flow “get-movies.ply.flow”, saving to an empty folder somewhere.
- Your newly-created flow should appear, containing two steps: Start and Stop:
- Expand the tree in Ply Tests view, and you should see get-movies.ply.flow.
Run your flow
- In Ply’s flow diagram toolbar (or in the Ply Tests item hover menu), click the run icon:
When prompted, select “Submit without verifying” (Submit is Ply-speak for “don’t check run results”). - To show flow/step statuses, the diagram automatically switches to Inspect mode, indicated by this icon in the toolbar mode dropdown:
- So far our flow doesn’t do anything interesting. However, this illustrates a couple of points:
- In Inspect mode, each step that executed is drawn with a heavy border around it:
- VS Code’s output window shows what happened:
Running flow 'get-movies.ply.flow' Executing step: "s1" Executing step: "s2" Finished flow: "1770df52bde"
- In Inspect mode, each step that executed is drawn with a heavy border around it:
Add a Request step to your flow
The idea of Ply is to test an API by submitting HTTP requests and validating results. That’s where Request steps come in.
- Switch back to Select mode using the flow toolbar dropdown:
- Remove the link joining Start to Stop by selecting it and hitting the Delete key.
- From Ply’s toolbox view to the right of our diagram, drag in the step that’s labeled Request. Position it somewhere between Start and Stop.
- Double-click on the “New Request” label to rename it “Movie by Title”.
- If you double-click on the Request step somewhere other than its label, Ply Configurator pops up. After renaming, double-click “Movie by Title”
(or right-click and select Configure). Then enter this for its URL:
This points to ply-movies, our playground REST API containing horror movies from the 1930s.
Draw links between flow steps
- To draw new links, switch to Connect mode:
- Then click/drag your mouse to draw a link between Start and “Movie by Title”.
- Do the same between “Movie by Title” and Stop.
- Switch back to Select mode, and save your flow (File > Save File, or Ctrl/Cmd-S).
Run with expected results
- Click the Run icon again to execute your flow. This time when prompted, select “Create expected result from actual”.
- Notice that this time, the Output view displays a line saying: Request ‘s3’ PASSED. What actually happened was that Ply executed get-movies.ply.flow, created actual runtime results, and then copied those results to create an expected-results file before comparing.
- Double-click the “Movie by Title” step to inspect its Request and Response.
- Run your flow again. This time you won’t get prompted since expected results now exist.
- Right-click on “Movie by Title” and select “Compare Results”:
VS Code’s diff editor indicates there are a couple discrepancies between expected results (on the left) versus actual (on the right). Lines 1 and 7 both differ, but these differences are only comments; hence the checkmark in the left gutter of the editor. - Let’s modify expected results to purposely break our test flow. In the left-hand editor, change the director credit from
Tod Browing
toJames Whale
, and save. Then close the result files and run the flow again. This time the flow fails, and “Movie by Title” is bordered in red. Compare results again:
Now line 19 shows a significant difference. - Fix the director credit in expected results, save and close the expected results and comparison editors; then re-run get-movies.ply.flow. Make sure the test passes this time.
Use input values in a flow
Values let you externalize parts of your requests and results, making them dynamic as well as reusable. For example: you might want to run “get-movies.ply.flow” against different environments, so you’d parameterize its request URLs using values.
- Switch back to Select mode
- Configure the “Movie by Title” step by double-clicking, or by right-clicking and selecting “Configure”.
- On the Request tab, change the URL to this:
- Now save and run the flow again. You’ll be prompted to enter
${baseUrl}
and${title}
. Enter values as shown here and click Run.
The value for “title” is available to reference in any of your requests. If you run the flow again, Ply will remember to use “Dracula” for ${title}
and you won’t be bothered with a prompt. Try running with a different value:
- In the flow diagram toolbar, click the Values button:
- Instead of “Dracula”, enter “Frankenstein” for
${title}
; then click Run. - Right-click on the failed step and select Compare Results to see how the response compares for a different title.
- Click the Values toolbar button again to switch back to “Dracula” and confirm that Run succeeds.
You can also define a flow-wide value as part of the flow itself:
- Open the configurator at flow-level by double-clicking or right-clicking a blank spot on the canvas.
- Add a value named “title” and again set it to “Dracula”
This technique provides a fixed value that’s available to anyone running your flow without them having to enter it.
Food for thought:
Why is “baseUrl” not a good candidate to specify in a flow definition this way?
Reference previous results in a downstream step
Suppose we add a request in our flow to test a slightly different endpoint.
- Drag another Request step onto the canvas and label it “Movie by ID”.
- Link it downstream of the “Movie by Title” request.
- We know Dracula’s
id
from our previous request, so enter this URL:
- Now save and run get-movies.ply.flow. The new step will fail since we haven’t added it’s expected results.
- Right-click on “Movie by ID” and select “Compare Results”. The expected result (on the left) is empty. Select all lines in the actual result on the right and copy to the clipboard.
- Now click the “Open Result File” Code Lens in expected result, and paste everything right before the Stop step near the bottom. As before, edit the response headers to include only ‘content-type’.
- Run the flow again, and it should succeed. You may need to iterate a time or two to make things work.
There’s an obvious drawback here in our hardcoding of id
in “Movie by ID”. We can avoid hardcoding using an expression
that references our previous “Movie by Title” response.
- Reconfigure “Movie by ID” step to specify its request URL like this:
An expression that starts with
${@
is Ply’s special syntax for referring to previous requests/responses. Here we’re grabbing the ‘s3’ (“Movie by Title”) step’s response body, indexing to the zeroth element of the movies array, and getting itsid
value. So effectively our flow is testing that the same movie we retrieved by title can also be retrieved by its ID. - In fact, it’s a good idea to change the expected result for “Movie by ID” to also use dynamic placeholders for
url
andid
:Movie by ID: id: s4 request: url: '${baseUrl}/movies/${@s3.response.body.movies[0].id}' method: GET headers: {} response: status: code: 200 message: OK headers: content-type: application/json; charset=utf-8 body: |- { "credits": [ { "name": "Tod Browning", "role": "director" }, { "name": "Bela Lugosi", "role": "actor" }, { "name": "Helen Chandler", "role": "actor" }, { "name": "David Manners", "role": "actor" }, { "name": "Dwight Frye", "role": "actor" }, { "name": "Edward Van Sloan", "role": "actor" } ], "description": "What's even more amazing than Lugosi's out-of-body performance is the fact that the finest horror movie ever made was filmed within 2 years of the advent of talking pictures.", "id": "${@s3.response.body.movies[0].id}", "poster": "drac.jpg", "rating": 5, "title": "Dracula", "webRef": { "ref": "tt0021814", "site": "imdb.com" }, "year": 1931 } status: 200 message: OK
Run a step by itself
As you’re building out a Ply flow by adding new steps, sometimes you may want to run a single step in isolation to test it without running the whole flow. Let’s run the “Movie by ID” step that we just inserted.
- Open get-movies.ply.flow in Select mode.
- Right-click on “Movie by ID”, and select Run.
- This time when you’re prompted for values, you’ll observe that
${@s3.response.body.movies[0].id}
is required, and that Ply knows this value from our previous flow run.
- Double-click “Movie by ID” to review its request and response to make sure they’re as expected.
Embedded Subflows
Embedded subflows are included in a main flow to perform setup and teardown actions.
Next Topic: Steps