opa test: Unit Test Rego Policies in CI
opa test discovers Rego rules whose names start with test_ and evaluates them, failing the run if any test is false or errors.
Policies are code and deserve tests. opa test executes every test_ rule under the paths you give it, so you catch a broken deny rule before it blocks a real deployment.
What it does
opa test loads the paths you pass, finds rules named test_* , and evaluates each one. A test passes if it evaluates to true and fails if it is false, undefined, or raises an error. It prints a summary and exits non-zero on any failure.
Common usage
# run all tests under the policy directory
opa test policy/ -v
# with code coverage and a minimum threshold
opa test policy/ --coverage --threshold 80
# run a single file plus its test file
opa test policy/deny.rego policy/deny_test.rego -vOptions
| Flag | What it does |
|---|---|
| -v, --verbose | Show output for passing tests too |
| --coverage | Report per-file coverage of the policy code |
| --threshold <n> | Fail if coverage is below this percentage |
| -r, --run <regex> | Only run tests whose name matches the regex |
| --bench | Benchmark the tests instead of just running them |
| -f, --format <fmt> | Output format: pretty, json, gobench |
In CI
Run opa test as a required check on every policy PR, and add --coverage --threshold to stop untested rules from merging. Test files conventionally live next to the policy as <name>_test.rego. The JSON format (-f json) is easy to archive as a test report.
Common errors in CI
"FAIL: data.main.test_deny_missing_label" with "FAIL (0s)" in the summary means that assertion evaluated to false. "ERROR: ... rego_type_error" means the test itself has a type bug. "no test cases found" (an empty run that still exits 0) usually means the path is wrong or the rules are not prefixed test_. A coverage run below --threshold exits 2.