Example-based testing#
The simplest form of verification in Crochet is the use of examples. In this form one has a specific scenario of the program in mind, and then verifies that the program behaves in that specific way. Examples are used for verifying small pieces of the program, rather than the entire program. And this process is generally called “unit testing”.
Test declarations#
Crochet’s support for example testing comes in the form of
test declarations. Each of these test declarations can cover
one of these scenarios, and verifications are done with the
assert
expression.
For example, consider the case where we have a command to display the list of items in an inventory with your usual English conjunctions. An example test for it could look like the following:
test "inventory display with conjunctions" do
assert (#inventory with: [] | show) === "You're not carrying anything.";
assert (#inventory with: [rose] | show) === "You're carrying [rose].";
assert (#inventory with: [rose, watch, old-coin] | show)
=== "You're carrying [rose], [watch], and [old-coin].";
end
Here we have three different assert
expressions that verify
different possibilities of displaying an inventory. When one isn’t
carrying anything, “You’re not carrying anything.” should be displayed.
But when they’re carrying multiple items, we’d expect something
more along the lines of “You’re carrying a rose, a watch, and an old coin.”.
Convenience for command tests#
Though you can always use the test declaration syntax, there’s a slightly
more convenient syntax for describing examples for a single command.
Instead of writing the separated test declaration, as above, we could
have added a test block to the inventory show: _
command itself:
command inventory show do
condition
when self.items is-empty => ...;
when self.items size === 1 => ...;
otherwise => ...;
end
test
assert (#inventory with: [] | show) === "You're not carrying anything.";
assert (#inventory with: [rose] | show) === "You're carrying [rose].";
assert (#inventory with: [rose, watch, old-coin] | show)
=== "You're carrying [rose], [watch], and [old-coin].";
end
This convenience syntax works exactly like the separated test declaration, but it uses the name of the command as a description.
Testing effects#
Warning
Effectful testing is still in discovery; this section will be expanded in the future.
When the pieces of program you want to test only depend on the data you’re using, your examples will consist of constructing the data, executing a command, and then comparing the resulting data with what you expected to happen.
But testing programs that have effects requires more sophisticated examples. And that’s because effects usually do things outside of what can be reasonably verified in Crochet. So one approach to testing these programs is to use a handler that, instead of doing things outside of Crochet, just keeps track of what was supposed to happen. The examples may then verify that what was supposed to happen in the program really matches what the program should be doing.