Write the tests

The test framework (in build.rs) reads *.jsonl files in the tests/fixtures/indicators/ directory. Each *.jsonl file is prefixed with an indicator code: for example, R038.jsonl and R038-tenderer.jsonl. The test framework runs the indicators command with that indicator enabled, and compares the output to the corresponding *.expected file: for example, R038.expected and R038-tenderer.expected.

The test file(s) for an indicator should:

  • Cause the indicator to return a result (to test for true positives)

  • Include data that covers any exclusions or edge cases (to test against false positives)

  • Not include data that is irrelevant to the indicator (to make the test readable)

You can use the ocid field to describe each compiled release.

You can use single letters for identifiers, for example:

  • Identifier to be Flagged

  • Buyer

  • Procuring entity

  • Supplier of an active award

  • Supplier of a Cancelled award

  • Supplier of an Unsuccessful award

  • Tenderer of a Invited bid

  • Tenderer of a Pending bid

  • Tenderer of a Valid bid

  • Tenderer of a Disqualified bid

  • Winning tenderer

  • Losing tenderer

Example

Edit the R999.jsonl and R999.expected files in the tests/fixtures/indicators/ directory from Add boilerplate content. To only test whether the indicator returns a result, replace the contents of the files with:

{"ocid":"F","bids":{"details":[{"status":"valid"}]},"awards":[{"status":"active"}]}

And:

{"OCID":{"F":{"R999":1.0}}}

Try it!

If you run:

cargo test

All tests should pass, including:

test tests::r999 ... ok

Advanced tests

If the indicator has many configurations, add test files for each configuration.

When the test framework reads *.jsonl files in the tests/fixtures/indicators/ directory, it splits the basename on hyphens (-) into parts. The first part is the indicator code.

If one part remains, this last part is ignored. It serves only to describe the test case. Example:

R038-tenderer.jsonl

If two parts remain, the second part is the configuration field, and the third part is the configuration value. If the third part is only digits, it is used as an integer. Otherwise, it is used as a string.

R048-minimum_contracting_processes-1.jsonl

If more than two parts remain, the second part is the configuration field. The remaining parts are key-value pairs for a HashMap, in which the keys are strings and the values are integers.

R003-procurement_method_details-x-5-y-10.jsonl

Note

To use a pipe-separated list, replace the pipe with a plus sign (+).

R003-procurement_method-open+selective.jsonl

Tip

If you need more flexibility (for example, f64), create an issue on GitHub.

Next step

Finally, you can add documentation.