Skip to main content
Rule ID: AE-TEST-001 · Severity: High · Category: Testing · Auto-fixable: No

Why this rule

An agent that writes code in a language with no automated tests has no way to verify its own work. Tests are the agent’s exit condition — without them it can only produce a diff, not a proof. The AGENTS.md standard treats the test command as one of the highest-value pieces of context an agent can have. AE-TEST-001 checks that there is actually something to run — before AE-AUTO-001 checks that the command is discoverable.

What triggers it

Charter detects active languages from manifest files committed to the repo:
LanguageManifest
Gogo.mod
JavaScript / TypeScriptpackage.json
RustCargo.toml
Pythonpyproject.toml or requirements.txt
Java / Kotlinpom.xml or build.gradle
Ruby, C#, PHPEquivalents
A language is only active when its manifest is present and the repo contains at least one non-test source file for that language outside tooling directories (scripts/, vendor/, node_modules/, dist/, build/). For each active language, Charter checks whether at least one test file exists using standard naming conventions:
LanguageTest file patterns
Go*_test.go
JavaScript / TypeScript*.test.*, *.spec.*
Pythontest_*.py, *_test.py, conftest.py
RustFiles under tests/, inline #[cfg(test)] markers
Java / Kotlin*Test.java, *Test.kt
Files in directories named test/, tests/, spec/, or __tests__/ also count, regardless of language.
Charter detects active languages by manifest, not by line count. A go.mod with one .go source file (non-test) counts as an active language and requires at least one test file.

Examples

A Go module with source files under internal/ but no *_test.go file anywhere:
my-service/
├── go.mod
├── internal/
│   ├── scorer.go
│   └── parser.go
└── cmd/
    └── main.go
# no *_test.go files → flagged High
A TypeScript project with source files but no test files:
my-app/
├── package.json
├── src/
│   └── index.ts
# no *.test.ts, *.spec.ts, or __tests__/ → flagged High

How to fix

Add a minimal test file for each active language that Charter flags. The test does not need comprehensive coverage — Charter checks for presence, not coverage percentage or pyramid shape.
1

Identify the active languages

Run charter doctor or charter explain AE-TEST-001 to see which languages are flagged and which manifest triggered each one.
2

Add a minimal test file

Create at least one test file using the language’s standard naming convention. A single passing test satisfies the rule.
3

Verify the finding clears

Run charter doctor again to confirm the finding no longer appears.

Score impact

High (−10); no hard cap. If multiple active languages all lack tests, each fires a separate finding instance.

Edge cases

AE-TEST-001 does not fire when no recognized code language is active. A repo containing only Markdown, YAML config, or tooling scripts is not penalized.
A //go:embed’d web asset (e.g. a report.js embedded into a Go binary) is a bundled resource, not a language surface. It does not activate JavaScript/TypeScript even when a build-tooling package.json is present.
A lone *.rb Homebrew formula with no Gemfile, or a stray *.py helper with no pyproject.toml, is not an active language and does not require tests.
Rust inline unit tests count via the #[cfg(test)] / #[test] content signal — no separate tests/ directory is required.

AE-AUTO-001

Requires a discoverable command to run the tests that this rule checks for.

AE-CI-002

Requires CI to run those tests on every pull request.

CLI

charter explain AE-TEST-001