/testing-codegen
Guide for testing workflows and code generation commands in Biome. Use when running snapshot tests for lint rules, managing insta snapshots, or regenerating analyzer/parser/formatter code after changes.
$ npx -y skills add biomejs/biome --skill testing-codegen --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/testing-codegen
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guide for testing workflows and code generation commands in Biome. Use when running snapshot tests for lint rules, managing insta snapshots, or regenerating analyzer/parser/formatter code after changes.
SKILL.md
testing-codegen.SKILL.mdname: testing-codegen
description: Guide for testing workflows and code generation commands in Biome. Use when running snapshot tests for lint rules, managing insta snapshots, or regenerating analyzer/parser/formatter code after changes.
compatibility: Designed for coding agents working on the Biome codebase (github.com/biomejs/biome).
Purpose
Use this skill for testing and code generation. Covers snapshot testing with `insta` and code generation commands.
Prerequisites
1. Install required tools: `just install-tools` (installs `cargo-insta`) 2. Install pnpm: `curl -fsSL https://get.pnpm.io/install.sh | sh -` in repo root 3. Understand which changes require code generation
Common Workflows
Run Tests
# Run all tests
cargo test
# Run tests for specific crate
cd crates/biome_js_analyze
cargo test
# Run specific test
cargo test quick_test
# Show test output (for dbg! macros)
cargo test quick_test -- --show-output
# Run tests with just (uses CI test runner)
just test
# Test specific crate with just
just test-crate biome_cli
Quick Test for Rules
Fast iteration during development:
// In crates/biome_js_analyze/tests/quick_test.rs
// Modify the quick_test function:
const SOURCE: &str = r#"
const x = 1;
var y = 2;
"#;
let rule_filter = RuleFilter::Rule("nursery", "noVar");Run:
just qt biome_js_analyze
Quick Test for Parser Development
**IMPORTANT:** Use this instead of building full Biome binary for syntax inspection - it's much faster!
For inspecting AST structure when implementing parsers or working with embedded languages:
// In crates/biome_html_parser/tests/quick_test.rs
// Modify the quick_test function:
#[test]
pub fn quick_test() {
let code = r#"<button on:click={handleClick}>Click</button>"#;
let source_type = HtmlFileSource::svelte();
let options = HtmlParserOptions::from(&source_type);
let root = parse_html(code, options);
let syntax = root.syntax();
dbg!(&syntax, root.diagnostics(), root.has_errors());
}Run:
just qt biome_html_parser
The `dbg!` output shows the full AST tree structure, helping you understand:
- How directives/attributes are parsed (e.g., `HtmlAttribute` vs `SvelteBindDirective`)
- Whether values use `HtmlString` (quotes) or `HtmlTextExpression` (curly braces)
- Token ranges and offsets needed for proper snippet creation
- Node hierarchy and parent-child relationships
Snapshot Testing with Insta
Run tests and generate snapshots:
cargo test
Review generated/changed snapshots:
# Interactive review (recommended)
cargo insta review
# Accept all changes
cargo insta accept
# Reject all changes
cargo insta reject
# Review for specific test
cargo insta review --test-runner nextest
Snapshot commands:
- `a` - accept snapshot
- `r` - reject snapshot
- `s` - skip snapshot
- `q` - quit
Pruning Orphaned Snapshots
When tests are removed or renamed, their old snapshot files become orphaned. **Never delete snapshot files manually with `rm`** — always use insta's built-in pruning:
# Delete unreferenced snapshots after a successful test run
cargo insta test --unreferenced delete -p <crate_name>
# Or scoped to specific tests
cargo insta test --unreferenced delete -p biome_cli --test main -- "handle_vue"
This runs the tests first, then deletes any `.snap` files that no test references. It is the only safe way to clean up snapshots — manual `rm` risks deleting snapshots that are still needed or creating git conflicts.
Test Lint Rules
# Test specific rule by name
just test-lintrule noVar
# Run from analyzer crate
cd crates/biome_js_analyze
cargo test
Create Test Files
**Single file tests** - Place in `tests/specs/{group}/{rule}/` under the appropriate `*_analyze` crate for the language:
tests/specs/nursery/noVar/
├── invalid.js # Code that should generate diagnostics
├── valid.js # Code that should not generate diagnostics
└── options.json # Optional: rule configuration
**File and folder naming conventions (IMPORTANT):**
- Use `valid` or `invalid` in file names or parent folder names to indicate expected behaviour.
- Files/folders with `valid` in the name (but not `invalid`) are expected to produce **no diagnostics**.
- Files/folders with `invalid` in the name are expected to produce **diagnostics**.
- When testing cases inside a folder, prefix the name of folder using `valid`/`invalid` e.g. `validResolutionReact`/`invalidResolutionReact`
tests/specs/nursery/noShadow/
├── invalid.js # should generate diagnostics
├── valid.js # should not generate diagnostics
├── validResolutionReact/
└───── file.js # should generate diagnostics
└── file2.js # should not generate diagnostics
**Multiple test cases** - Use `.jsonc` files with arrays:
// tests/specs/nursery/noVar/invalid.jsonc
[
"var x = 1;",
"var y = 2; var z = 3;",
"for (var i = 0; i < 10; i++) {}"
]**Test-specific options** - Create `options.json`:
{
"linter": {
"rules": {
"nursery": {
"noVar": {
"level": "error",
"options": {
"someOption": "value"
}
}
}
}
}
}Top-Level Comment Convention (REQUIRED)
Every test spec file **must** begin with a top-level comment declaring whether it expects diagnostics. The test runner (`assert_diagnostics_expectation_comment` in `biome_test_utils`) enforces this and panics if the rules are violated.
Write the marker text using whatever comment syntax the language under test supports. For languages that do not support comments at all, rely on the file/folder naming convention (`valid`/`invalid`) instead.
**For files whose name contains "valid" (but not "invalid"):**
The comment is **mandatory** — the test panics if it is absent.
**For files whose nam
Read more
name: testing-codegen description: Guide for testing workflows and code generation commands in Biome. Use when running snapshot tests for lint rules, managing insta snapshots, or regenerating analyzer/parser/formatter code after changes. compatibility: Designed for coding agents working on the Biome codebase (github.com/biomejs/biome).
Purpose
Use this skill for testing and code generation. Covers snapshot testing with `insta` and code generation commands.
Prerequisites
1. Install required tools: `just install-tools` (installs `cargo-insta`) 2. Install pnpm: `curl -fsSL https://get.pnpm.io/install.sh | sh -` in repo root 3. Understand which changes require code generation
Common Workflows
Run Tests
# Run all tests cargo test # Run tests for specific crate cd crates/biome_js_analyze cargo test # Run specific test cargo test quick_test # Show test output (for dbg! macros) cargo test quick_test -- --show-output # Run tests with just (uses CI test runner) just test # Test specific crate with just just test-crate biome_cli
Quick Test for Rules
Fast iteration during development:
// In crates/biome_js_analyze/tests/quick_test.rs
// Modify the quick_test function:
const SOURCE: &str = r#"
const x = 1;
var y = 2;
"#;
let rule_filter = RuleFilter::Rule("nursery", "noVar");Run:
just qt biome_js_analyze
Quick Test for Parser Development
**IMPORTANT:** Use this instead of building full Biome binary for syntax inspection - it's much faster!
For inspecting AST structure when implementing parsers or working with embedded languages:
// In crates/biome_html_parser/tests/quick_test.rs
// Modify the quick_test function:
#[test]
pub fn quick_test() {
let code = r#"<button on:click={handleClick}>Click</button>"#;
let source_type = HtmlFileSource::svelte();
let options = HtmlParserOptions::from(&source_type);
let root = parse_html(code, options);
let syntax = root.syntax();
dbg!(&syntax, root.diagnostics(), root.has_errors());
}Run:
just qt biome_html_parser
The `dbg!` output shows the full AST tree structure, helping you understand:
- How directives/attributes are parsed (e.g., `HtmlAttribute` vs `SvelteBindDirective`)
- Whether values use `HtmlString` (quotes) or `HtmlTextExpression` (curly braces)
- Token ranges and offsets needed for proper snippet creation
- Node hierarchy and parent-child relationships
Snapshot Testing with Insta
Run tests and generate snapshots:
cargo test
Review generated/changed snapshots:
# Interactive review (recommended) cargo insta review # Accept all changes cargo insta accept # Reject all changes cargo insta reject # Review for specific test cargo insta review --test-runner nextest
Snapshot commands:
- `a` - accept snapshot
- `r` - reject snapshot
- `s` - skip snapshot
- `q` - quit
Pruning Orphaned Snapshots
When tests are removed or renamed, their old snapshot files become orphaned. **Never delete snapshot files manually with `rm`** — always use insta's built-in pruning:
# Delete unreferenced snapshots after a successful test run cargo insta test --unreferenced delete -p <crate_name> # Or scoped to specific tests cargo insta test --unreferenced delete -p biome_cli --test main -- "handle_vue"
This runs the tests first, then deletes any `.snap` files that no test references. It is the only safe way to clean up snapshots — manual `rm` risks deleting snapshots that are still needed or creating git conflicts.
Test Lint Rules
# Test specific rule by name just test-lintrule noVar # Run from analyzer crate cd crates/biome_js_analyze cargo test
Create Test Files
**Single file tests** - Place in `tests/specs/{group}/{rule}/` under the appropriate `*_analyze` crate for the language:
tests/specs/nursery/noVar/ ├── invalid.js # Code that should generate diagnostics ├── valid.js # Code that should not generate diagnostics └── options.json # Optional: rule configuration
**File and folder naming conventions (IMPORTANT):**
- Use `valid` or `invalid` in file names or parent folder names to indicate expected behaviour.
- Files/folders with `valid` in the name (but not `invalid`) are expected to produce **no diagnostics**.
- Files/folders with `invalid` in the name are expected to produce **diagnostics**.
- When testing cases inside a folder, prefix the name of folder using `valid`/`invalid` e.g. `validResolutionReact`/`invalidResolutionReact`
tests/specs/nursery/noShadow/ ├── invalid.js # should generate diagnostics ├── valid.js # should not generate diagnostics ├── validResolutionReact/ └───── file.js # should generate diagnostics └── file2.js # should not generate diagnostics
**Multiple test cases** - Use `.jsonc` files with arrays:
// tests/specs/nursery/noVar/invalid.jsonc
[
"var x = 1;",
"var y = 2; var z = 3;",
"for (var i = 0; i < 10; i++) {}"
]**Test-specific options** - Create `options.json`:
{
"linter": {
"rules": {
"nursery": {
"noVar": {
"level": "error",
"options": {
"someOption": "value"
}
}
}
}
}
}Top-Level Comment Convention (REQUIRED)
Every test spec file **must** begin with a top-level comment declaring whether it expects diagnostics. The test runner (`assert_diagnostics_expectation_comment` in `biome_test_utils`) enforces this and panics if the rules are violated.
Write the marker text using whatever comment syntax the language under test supports. For languages that do not support comments at all, rely on the file/folder naming convention (`valid`/`invalid`) instead.
**For files whose name contains "valid" (but not "invalid"):**
The comment is **mandatory** — the test panics if it is absent.
**For files whose nam
A toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.
Repo: biomejs/biome
Other skills on biome.
- /biome-code-review
Static, read-only code review of a Biome (github.com/biomejs/biome) pull request, local branch, commit range, diff, or working tree being prepared as a PR. Applies Biome's own conventions - nursery placement and naming for lint rules, diagnostics quality, allocation and borrow
Open skill - /biome-developer
General development best practices and common gotchas when working on Biome. Use for avoiding common mistakes, understanding Biome-specific patterns (AST, syntax nodes, string extraction, embedded languages), and learning technical tips.
Open skill - /changeset
Guide for creating and writing proper changesets for Biome PRs. Use when a PR introduces user-visible changes (bug fixes, new features, rule changes, formatter changes, parser changes) that need a changeset entry for the CHANGELOG. Trigger when creating changesets, writing
Open skill - /diagnostics-development
Guide for creating high-quality, user-friendly diagnostics in Biome. Use when creating diagnostics for lint rules, adding helpful advice to error messages, implementing code frame displays, or improving diagnostic quality.
Open skill - /doc-comments
How to write inline comments, rustdoc, and module documentation in the Biome codebase. The audience is Biome developers reading the source, not end users. Use whenever writing or editing `//` comments, `///` item docs, or `//!` module docs — including comments added incidentally
Open skill - /eslint-migrate-options
Guide for implementing ESLint-to-Biome rule option migrators inside `biome migrate eslint`. Use whenever you add or update a Biome lint rule that has an ESLint source rule with configurable options, need to deserialize plugin-specific ESLint options, or need custom migration
Open skill

