Testing Guardrails
Ensure tests are executed in CI, passing, and meet coverage thresholds. Works with any collector that writes to the normalized .testing paths.
testing to your lunar-config.yml:uses: github://earthly/lunar-lib/policies/testing@v1.0.0
Included Guardrails
This policy includes 5 guardrails that enforce standards for your testing and quality.
executed
Ensures tests were executed in CI. Fails if no test execution data is found.
passing
Ensures all tests pass. Fails if test pass/fail data is not available.
coverage-collected
Ensures coverage data is being collected in CI. Fails if no coverage data is found.
coverage-reported
Ensures coverage percentage is being reported. Fails if coverage runs but percentage is not captured.
min-coverage
Enforces a minimum code coverage threshold (default 80%). Fails if coverage data is not available.
How Guardrails Fit into Lunar
Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.
Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.
Learn How Lunar Works →Required Integrations
This policy evaluates data gathered by one or more of the following integration(s).
Make sure to enable them in your lunar-config.yml.
Configuration
Configure this policy in your lunar-config.yml.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
required_languages
|
Required | — | Comma-separated list of languages to check (e.g., "go,python,nodejs,java"). If empty, applies to all components with any detected language project. Components without .lang.* are always skipped (e.g., docs-only repos). |
min_coverage
|
Optional |
80
|
Minimum required coverage percentage (for min-coverage check) |
Documentation
View on GitHubTesting Guardrails
Validates that tests are executed, pass, and meet coverage thresholds.
Overview
This policy enforces that tests are executed in CI, all tests pass, and code coverage meets minimum thresholds. It is language-agnostic and works with any collector that writes to the normalized .testing paths (e.g., the golang collector for Go projects, codecov for coverage data).
Policies
This plugin provides the following policies (use include to select a subset):
| Policy | Description | Failure Meaning |
|---|---|---|
executed |
Tests should be executed in CI | No test execution data found |
passing |
All tests should pass | Tests are failing or pass/fail data unavailable |
coverage-collected |
Coverage data should be collected | No coverage data found |
coverage-reported |
Coverage percentage should be reported | Coverage runs but percentage not captured |
min-coverage |
Coverage should meet minimum threshold | Coverage below threshold or no coverage data |
Required Data
This policy reads from the following Component JSON paths:
| Path | Type | Provided By |
|---|---|---|
.testing |
object | Any test collector (e.g., golang) |
.testing.all_passing |
boolean | Collectors that parse test results |
.testing.coverage |
object | Any coverage collector (e.g., codecov, golang) |
.testing.coverage.percentage |
number | Coverage collectors that report percentage |
Note: All checks fail (not skip) when expected data is missing for a valid language project. This ensures the compliance score accurately reflects missing test/coverage data. Checks only skip when the component is not a language project (e.g., docs-only repos).
Installation
Add to your lunar-config.yml:
policies:
- uses: github://earthly/lunar-lib/policies/testing@main
on: ["domain:engineering"]
enforcement: report-pr
# include: [executed, passing] # Only run specific checks (omit to run all)
with:
# required_languages: Only enforce for components with detected language projects
# Checks for .lang.<language> existence (set by language collectors)
# Skips docs-only repos, infrastructure components, repos that just run scripts
required_languages: "go,python,nodejs,java"
# min_coverage: Minimum coverage percentage for min-coverage check
min_coverage: "80"
Inputs:
| Input | Default | Description |
|---|---|---|
required_languages |
"" |
Comma-separated languages to check. If empty, applies to all components with any detected language project. Components without .lang.* are always skipped. |
min_coverage |
"80" |
Minimum coverage percentage for the min-coverage check |
Examples
Passing Example — Full Data
Tests executed, passing, and good coverage:
{
"lang": {"go": {"version": "1.22"}},
"testing": {
"source": {
"framework": "go test",
"integration": "ci"
},
"results": {
"total": 156,
"passed": 156,
"failed": 0,
"skipped": 0
},
"all_passing": true,
"coverage": {
"percentage": 85.5
}
}
}
Failing Example — No Tests Executed (executed policy)
When a language project exists but no test data:
{
"lang": {"go": {"version": "1.22"}}
}
Failure message: "No test execution data found. Ensure tests are configured to run in CI."
Note: All testing checks fail together when data is missing for a valid language project.
Failing Example — Tests Failing (passing policy)
{
"lang": {"go": {"version": "1.22"}},
"testing": {
"all_passing": false
}
}
Failure message: "Tests are failing. Check CI logs for test failure details."
Failing Example — Low Coverage (min-coverage policy)
{
"lang": {"go": {"version": "1.22"}},
"testing": {
"coverage": {
"percentage": 65.0
}
}
}
Failure message: "Coverage 65.0% is below minimum 80%"
Failing Example — No Coverage Data (min-coverage policy)
When coverage isn't collected but component is a valid language project:
{
"lang": {"go": {"version": "1.22"}},
"testing": {
"source": {"framework": "go test"}
}
}
The min-coverage check fails with message: "No coverage data collected. Configure a coverage tool to run in your CI pipeline."
Skipped Example — Non-Language Component
When no language project is detected (e.g., docs-only repo):
{
"repo": {"readme": {"exists": true}}
}
All testing checks are skipped with message: "No language project detected"
Remediation
When this policy fails, you can resolve it by:
executedfailure: Configure your CI pipeline to run tests and ensure a collector is capturing test execution datapassingfailure: Fix the failing tests in your codebase—check CI logs for specific test failure detailscoverage-collectedfailure: Configure a coverage collector to run in your CI pipelinecoverage-reportedfailure: Ensure your coverage tool is configured to report metrics (percentage)min-coveragefailure: Add more tests to increase code coverage, or adjust themin_coverageinput
Open Source
This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.
Common Use Cases
Explore how individual guardrails work with specific integrations.
Ready to Automate Your Standards?
See how Lunar can turn your engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 100+ built-in guardrails.