Skip to main content

Testing Minder Rules

mindev test is the supported mechanism for verifying rule behavior, designed for integration into CI/CD pipelines as well as standalone local usage. It allows you to write automated unit tests for your custom rule types offline, without needing a live provider or real credentials.

The testing framework is built on Starlark (a Python-like configuration language) and uses mock HTTP responses and mock filesystems to simulate provider APIs and git repositories.

Running Tests Locally

To run Starlark tests in a directory containing *_test.star files:

mindev test .

By default, mindev test . will recursively find and run all *_test.star files in the current directory and its subdirectories.

Generating JUnit Output

For integration with test reporting tools, generate a JUnit XML report with:

mindev test . --junit-file report.xml

Creating a Test File

Test files must be written in Starlark and have a _test.star suffix. By convention, they are placed in the same directory as the rule type definition.

If your rule type is named branch_protection_enforce_admins.yaml, create a test file named branch_protection_enforce_admins_test.star.

A test file consists of one or more functions that start with test_. The mindev test command will discover and run these functions automatically.

Basic example:

# branch_protection_enforce_admins_test.star

ENTITY = {
"owner": "mindersec",
"name": "minder",
"type": "repository",
"default_branch": "main"
}

def build_mock_http(enabled):
return {
"/repos/mindersec/minder/branches/main/protection": body({
"enforce_admins": {"enabled": enabled}
})
}

def test_enforce_admins_pass():
result = eval(
rule="branch_protection_enforce_admins",
entity=ENTITY,
profile={"enforce_admins": True},
mock_http=build_mock_http(True)
)
assert result["status"] == "pass", "Expected rule to pass"

def test_enforce_admins_fail():
result = eval(
rule="branch_protection_enforce_admins",
entity=ENTITY,
profile={"enforce_admins": True},
mock_http=build_mock_http(False)
)
assert result["status"] == "fail", "Expected rule to fail"

Starlark Runtime Reference

The testing environment provides several built-in functions to evaluate rules and mock external data.

eval()

The eval() function executes a rule type against a mock environment and returns a result dictionary.

Arguments:

  • rule (Required, String): Name or file path of the rule type to evaluate (e.g. "branch_protection_enforce_admins").
  • entity (Optional, Dict): The entity object dictionary to evaluate against.
  • profile (Optional, Dict): Profile configuration dictionary to evaluate rule parameters.
  • params (Optional, Dict): Rule parameters dictionary (matches the rule's param_schema).
  • mock_http (Optional, Dict): A dictionary mapping URL endpoint paths to mock HTTP responses generated by body() or code().
  • mock_fs (Optional, Dict): A dictionary mapping file paths to file content strings for git ingest rules.
  • data_sources (Optional, List): A list of paths to datasource YAML files required by the rule type.

Return Value:

An object dictionary containing:

  • result["status"]: "pass", "fail", "skip", or "error"
  • result["message"]: String detailing the evaluation failure, skip reason, or error message (if any).
  • result["output"]: The evaluation output value returned by the rule (if any).

body() and code()

These helpers generate mock HTTP responses for mock_http:

  • body(payload): Returns a 200 OK HTTP response with payload (can be a dictionary, list, string, or number).
  • code(status_code): Returns an empty HTTP response with the given status code (e.g., code(404) or code(500)).

read_file()

Reads a file relative to the test file directory and returns its content as a string. Useful for reading test fixtures or JSON payloads:

payload = read_file("testdata/response.json")

txtar()

Parses a txtar archive string into a dictionary of file paths to file contents, ideal for mocking multi-file git repositories in mock_fs.

archive = read_file("testdata/repo.txtar")
files = txtar(archive)

result = eval(
rule="check_workflows",
mock_fs=files
)

Running Tests in CI/CD

To run Starlark rule tests automatically in GitHub Actions, use the official mindersec/minder-action/test action:

name: Rule Type Tests
on:
push:
branches: [main]
pull_request:

jobs:
test-rules:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run mindev test
uses: mindersec/minder-action/test@v1

You can also combine this with JUnit report publishing:

- name: Run mindev test with JUnit report
uses: mindersec/minder-action/test@v1
with:
flags: --junit-file report.xml

- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: always()
with:
report_paths: 'report.xml'