Skip to main content
Glama

Run Rego tests

rego_test

Run Rego unit tests with opa test to return pass/fail/skip/error counts and per-test records, filter tests by regex, gate coverage thresholds, and add verbose traces for debugging.

Instructions

Run Rego unit tests with opa test. Returns aggregate pass/fail/skip/error counts plus per-test records. errored counts tests OPA could not evaluate (a rule conflict, a raising built-in); such a test is neither a pass nor a failure, and a suite with any is not passing. Tests live in *_test.rego files; rule names beginning with test_ are picked up automatically. Use runPattern to filter by name regex; when no tests match, the error hint includes the pattern you supplied. Use threshold to gate on minimum coverage (returns COVERAGE_BELOW_THRESHOLD on failure). Use varValues: true with verbose: true to include local variable bindings in the trace -- essential for debugging table-driven tests written with every tc in cases { ... } to identify which case caused a failure. When tests use the test_x[case] parameterized form, OPA reports the rule as a single test whatever the number of cases; parameterizedGroups maps the rule name to a record per case and caseCounts totals them, so a failing rule says which case failed. Use ignorePatterns to exclude generated or fixture files. Use bundle: true when testing bundle-structured policy directories. Use timeout to raise the per-test limit beyond OPA's default 5s. With coverage or threshold the suite runs a second time for the coverage report, which is added to the results; it is left out when a test fails or errors, since opa reports no coverage for such a run.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "paths": "<paths>"
    },
    "name": "rego_test"
  }
}

Input Schema

NameRequiredDescriptionDefault
countNoNumber of times to repeat the suite (`--count N`). Default is 1. Useful for catching flaky tests. OPA stops at the first repetition that fails, so `repetitions` in the output reports how many actually ran, and each test is listed once carrying its worst outcome across them.
pathsYesTest directories or files. `opa test` looks for `*_test.rego` siblings of source files.
bundleNoLoad paths as OPA bundle roots (`--bundle`). Required when testing policies structured as bundles with a `manifest.json` at the root. Not needed for plain policy directories.
explainNoAdd a query-explanation trace to test records (`--explain`). `fails` traces only failing tests, `full` traces everything, `notes` surfaces `trace()` notes, `debug` is most verbose. Populates each record's `trace` field; pair with `verbose: true` for the human-readable trace output too.
timeoutNoPer-test timeout as a Go duration string, e.g. `"30s"` or `"2m"` (`--timeout`). OPA's default is 5s. Increase for tests that load large policy sets or call slow built-ins.
verboseNoEmit per-test pass/fail details.
coverageNoAdd per-line coverage (`coverage`, `coveragePct`) to the test results. The suite runs twice, once for the results and once for coverage. Coverage is left out, with a warning, when a test fails or errors: opa reports none for such a run.
thresholdNoMinimum coverage percentage required (0–100). Returns COVERAGE_BELOW_THRESHOLD when the tests pass but coverage falls below this value. Implies `coverage`.
varValuesNoInclude local variable bindings in trace output (`--var-values`). When a table-driven test using `every tc in cases { ... }` fails, the trace shows which `tc` triggered the failure. Has no effect unless `verbose: true` is also set (OPA only emits trace entries in verbose mode).
runPatternNoRun only tests whose names match this regular expression (passed as `--run`).
v0CompatibleNoRead the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it.
v1CompatibleNoOpt in to OPA v1.0-compatible behaviors (`--v1-compatible`).
ignorePatternsNoGlob patterns for files to exclude from the test run (`--ignore <pattern>`). Pass one pattern per array element. Useful for excluding generated or fixture files that contain no tests (e.g. `["*_generated.rego", "fixtures/**"]`).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv0.9.1
    • changedInput schema / properties / coverage / description
      Previous value: -"Include per-line coverage data. Switches output to coverage-report mode: test record counts are not available, but `coverage` and `coveragePct` fields are populated."New value: +"Add per-line coverage (`coverage`, `coveragePct`) to the test results. The suite runs twice, once for the results and once for coverage. Coverage is left out, with a warning, when a test fails or errors: opa reports none for such a run."
    • changedInput schema / properties / threshold / description
      Previous value: -"Minimum coverage percentage required (0–100). Returns COVERAGE_BELOW_THRESHOLD when actual coverage falls below this value. Implicitly enables coverage-report output mode."New value: +"Minimum coverage percentage required (0–100). Returns COVERAGE_BELOW_THRESHOLD when the tests pass but coverage falls below this value. Implies `coverage`."
  2. Changed1 schema field changedv0.8.0
    • changedInput schema / properties / v0Compatible / description
      Previous value: -"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load."New value: +"Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load. Where the tool also takes a query, the query is read as v0 too, with the future keywords imported so `in`, `every` and `some x in` still work in it."
  3. Changed1 schema field changedv0.7.0
    • addedInput schema / properties / v0Compatible
      Added value: +{
      +  "description": "Read the policy as Rego v0 (`--v0-compatible`), the syntax OPA used before 1.0: rules without `if`, partial sets as `deny[msg] { ... }`. Needed for a policy that has not been migrated, which OPA 1.x otherwise refuses to load.",
      +  "type": "boolean"
      +}
  4. Changed1 schema field changedv0.5.0
    • changedInput schema / properties / count / description
      Previous value: -"Number of times to repeat each test (`--count N`). Default is 1. Useful for measuring repeatability or catching flaky tests under load."New value: +"Number of times to repeat the suite (`--count N`). Default is 1. Useful for catching flaky tests. OPA stops at the first repetition that fails, so `repetitions` in the output reports how many actually ran, and each test is listed once carrying its worst outcome across them."
  5. Changed2 schema fields changedv0.1.20
    • addedInput schema / properties / explain
      Added value: +{
      +  "description": "Add a query-explanation trace to test records (`--explain`). `fails` traces only failing tests, `full` traces everything, `notes` surfaces `trace()` notes, `debug` is most verbose. Populates each record's `trace` field; pair with `verbose: true` for the human-readable trace output too.",
      +  "enum": [
      +    "fails",
      +    "full",
      +    "notes",
      +    "debug"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / v1Compatible
      Added value: +{
      +  "description": "Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`).",
      +  "type": "boolean"
      +}
  6. Changed4 schema fields changedv0.1.17
    • addedInput schema / properties / bundle
      Added value: +{
      +  "description": "Load paths as OPA bundle roots (`--bundle`). Required when testing policies structured as bundles with a `manifest.json` at the root. Not needed for plain policy directories.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / count
      Added value: +{
      +  "description": "Number of times to repeat each test (`--count N`). Default is 1. Useful for measuring repeatability or catching flaky tests under load.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / ignorePatterns
      Added value: +{
      +  "description": "Glob patterns for files to exclude from the test run (`--ignore <pattern>`). Pass one pattern per array element. Useful for excluding generated or fixture files that contain no tests (e.g. `[\"*_generated.rego\", \"fixtures/**\"]`).",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / timeout
      Added value: +{
      +  "description": "Per-test timeout as a Go duration string, e.g. `\"30s\"` or `\"2m\"` (`--timeout`). OPA's default is 5s. Increase for tests that load large policy sets or call slow built-ins.",
      +  "type": "string"
      +}
  7. Addedv0.1.13
  8. Removedv0.1.5
  9. Addedv0.1.2
  10. Removedv0.1.1
  11. First observedv0.1.0

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare `readOnlyHint: false` and `openWorldHint: true`; the description adds substantial behavior beyond that, including aggregate pass/fail/skip/error counts, the special meaning of `errored`, the second coverage run, coverage omission when tests fail or error, and `COVERAGE_BELOW_THRESHOLD` on gated failures. It also explains parameterized test reporting via `parameterizedGroups` and `caseCounts`. This is rich context that annotations do not cover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and every sentence carries useful information; there is little filler. The single dense paragraph is long for a 13-parameter tool and could be more easily scannable, but it avoids redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter test runner with no output schema, the description covers the important behavioral and output details an agent needs: aggregate counts, per-test records, coverage behavior, parameterized groups, case counts, repetitions, and error conditions. The gaps are minor, such as exact output field shapes, but not necessary for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents each parameter's meaning. The description adds some cross-parameter meaning not present in the schema, especially that `varValues: true` requires `verbose: true` to matter, that `threshold` implies coverage and returns a specific error, and that no-match `runPattern` failures include the supplied pattern. Much of the remaining parameter guidance repeats schema text, so it is stronger than baseline but not entirely additive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Run Rego unit tests with `opa test`." It is clearly a test-execution tool rather than an evaluation or formatting tool. However, it does not distinguish itself from the sibling `rego_test_multiroot`, leaving that routing decision implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage context for many parameters: use `runPattern` to filter, `threshold` to gate coverage, `varValues` with `verbose` for table-driven debugging, `ignorePatterns` for fixtures, `bundle: true` for bundle directories, and `timeout` for slow tests. It does not explicitly state when not to use this tool or name `rego_test_multiroot` as the alternative for multi-root suites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.