Test Guidelines
getsentry/sentry-react-native
Enforce Sentry React Native SDK test conventions for naming, structure, mocking, and fixtures with Jest.
Enforce Sentry Dart/Flutter SDK test conventions for naming, structure, and fixtures.
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install getsentry/sentry-dart test-guidelines --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/test-guidelines .claude/skills/test-guidelines && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .claude/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelinesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install getsentry/sentry-dart test-guidelines --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/test-guidelines .agents/skills/test-guidelines && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .agents/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install getsentry/sentry-dart test-guidelines --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/test-guidelines .cursor/skills/test-guidelines && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .cursor/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/getsentry/sentry-dart.git --path .agents/skills/test-guidelines--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install getsentry/sentry-dart test-guidelines --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/test-guidelines .gemini/skills/test-guidelines && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .gemini/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install getsentry/sentry-dart test-guidelinesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/test-guidelines .github/skills/test-guidelines && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .github/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add getsentry/sentry-dart --skill test-guidelines -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install getsentry/sentry-dart test-guidelines --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/getsentry/sentry-dart.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/test-guidelines .opencode/skills/test-guidelines && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "test-guidelines" agent skill from https://github.com/getsentry/sentry-dart/tree/main/.agents/skills/test-guidelines into .opencode/skills/test-guidelines/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-guidelines", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
test-guidelinesEnforce Sentry Dart/Flutter SDK test conventions for naming, structure, and fixtures.
Test Guidelines is an agent skill from getsentry/sentry-dart, published by the product's own GitHub organization. Enforce Sentry Dart/Flutter SDK test conventions for naming, structure, and fixtures. Use when writing tests, adding tests, modifying tests, reviewing test code, fixing failing tests, adding test coverage, TDD, test-first / red-green, reproducing bugs with tests, regression tests, or test refactoring in any package in this Melos monorepo.
Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/async.md`, `references/fixtures.md` and `references/mocking.md`).
It sits in Testing & QA, covering Test-driven development, Cross-platform mobile apps and Failing and flaky tests. It works with Sentry, Flutter and Dart. The repository describes itself as: Sentry SDK for Dart and Flutter. The licence is MIT.
Read from SKILL.md and the folder at commit 96d6367. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are dart).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Test Guidelines loads about 3.1k tokens when it runs, and up to ~4.7k if it reads all its reference files. Until then it costs about 89 tokens; SKILL.md has 1,047 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from getsentry/sentry-dart at commit 96d6367, republished under its MIT licence (© getsentry). 1,047 words, ~3,133 tokens.
.claude/skills/test-guidelines/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Apply these conventions to all new and modified tests across every package in this monorepo. Existing tests may not follow these conventions — do not refactor them unless asked.
Tests are easiest to write against code designed to accept its dependencies — when implementing the code under test, load design-first (where the seams go) and code-guidelines (the rules).
Work in vertical slices, not horizontal ones. One failing test → the minimal code that makes it pass → repeat. Each test is a tracer bullet: it proves one thin path end-to-end, and what you learn from it shapes the next.
Do not write all the tests first and then all the implementation. That horizontal slicing produces tests of imagined behavior — they assert the shape you guessed at, pass when the real behavior breaks, and commit you to a structure before you understand it. Write one test at a time, against behavior you can already reason about.
Fixing a bug? Reproduce it with a failing test first — see diagnosing-bugs for the loop.
lib/src/hub.dart → test/hub_test.dart.void main() { ... } entry point.group() matching the class or unit name. When the subject is a class or enum, write it with $ interpolation ('$SentryClient') so the name tracks renames; for other units (top-level functions, extensions) use a plain string — see Style rules.// GOOD: Mirrors source path, single main, single top-level group
// test/sentry_client_test.dart (for lib/src/sentry_client.dart)
void main() {
group('$SentryClient', () {
// all tests here
});
}
// AVOID: Multiple top-level groups or no group wrapper
void main() {
group('SentryClient capture', () { });
group('SentryClient close', () { });
}Nested group() + test() names MUST read as a sentence when concatenated.
Pattern: [Subject] [Context] [Variant] [Behavior]
| Depth | Role | Style | Example |
|---|---|---|---|
| Group 1 | Subject | Noun | Client |
| Group 2 | Context | when / in / during | when connected |
| Group 3 | Variant | with / given / using | with valid input |
| Test | Behavior | Verb phrase | sends message |
returns scope, throws ArgumentError, sends event to transport.should — prefer direct phrasing.$ interpolation in the string (group('$Hub', ...)) so a rename updates the test name. Never pass a bare Type literal — group(Hub, ...) is not allowed.'$MyExtension' is a compile error; '$myFunction' yields a closure string) — use a plain descriptive string there.// GOOD: Interpolated class subject, plain verb phrase
group('$Hub', () {
test('returns the scope', () { });
});
// AVOID: "should" prefix, bare Type literal as group name
group(Hub, () {
test('should return the scope', () { });
});If it doesn't read like a sentence, rename the groups:
// GOOD: "Hub returns the scope" reads as a sentence
group('$Hub', () {
test('returns the scope', () { });
});
// GOOD: "Hub when capturing sends event to transport"
group('$Hub', () {
group('when capturing', () {
test('sends event to transport', () { });
});
});
// AVOID: Doesn't read as a sentence ("Hub capture test event sent")
group('$Hub', () {
group('capture test', () {
test('event sent', () { });
});
});// GOOD: Simple variant in test name (2 groups + test)
group('$Hub', () {
group('when bound to client', () {
test('with valid DSN initializes correctly', () { });
test('with empty DSN throws ArgumentError', () { });
});
});
// AVOID: Unnecessary nesting (3 groups + test)
group('$Hub', () {
group('when bound to client', () {
group('with valid DSN', () {
test('initializes correctly', () { });
});
});
});// GOOD: Behavior carries the context; no redundant wrapper
group('$SentryAttribute', () {
test('string serializes value with string type', () { });
test('int serializes value with integer type', () { });
});
// AVOID: Wrapper context true of every test — pure noise
group('$SentryAttribute', () {
group('when serializing to JSON', () { // every test serializes
test('string serializes value with string type', () { });
test('int serializes value with integer type', () { });
});
});Use clear verb phrases indicating absence or failure:
| Pattern | When | Example |
|---|---|---|
does not <verb> | Behavior intentionally skipped | does not send event |
throws <ExceptionType> | Expecting an exception | throws ArgumentError |
returns null | Null result expected | returns null when missing |
ignores <thing> | Input deliberately ignored | ignores empty breadcrumbs |
// GOOD: Clear verb phrases indicating absence or failure
group('$Client', () {
group('when disabled', () {
test('does not send events', () { });
test('returns null for captureEvent', () { });
test('throws StateError', () { });
});
});
// AVOID: Vague negations or "should not" phrasing
group('$Client', () {
group('when disabled', () {
test('should not work', () { });
test('fails', () { });
test('no events', () { });
});
});Encapsulate setup in a Fixture class at the bottom of each test file, exposing a getSut() that builds the System Under Test with configurable, injectable dependencies. Initialize it in setUp() within the narrowest group that needs it. Always build options via defaultTestOptions() from test_utils.dart — never construct SentryOptions directly.
class Fixture {
final transport = MockTransport();
final options = defaultTestOptions();
SentryClient getSut({bool attachStacktrace = true}) {
options.attachStacktrace = attachStacktrace;
options.transport = transport;
return SentryClient(options);
}
}Full rules — Fixture placement, setUp/tearDown scoping, setUpAll caveats, and the defaultTestOptions() rule — in references/fixtures.md.
Test the behavior owned by your change.
Prefer tests that would fail if your change's intended contract were broken: user-visible behavior, public API behavior, meaningful branching logic, data transformations, integration wiring, precedence rules, error handling, and regressions your change could realistically introduce.
Avoid tests that merely re-prove guarantees owned somewhere else, such as a shared helper, base class, framework, serializer, collection type, generated model, or value object that already has focused coverage. A caller test should not exist just to show that its dependencies still work.
Before adding a test, ask:
Do test delegated behavior when the delegation is load-bearing for your change's own contract. For example, preserving user input, choosing precedence between sources, wiring the correct helper, enforcing a public API promise, or covering a past regression can all deserve caller-level tests even if a helper implements part of the behavior.
Good tests make the intended contract harder to break. Noisy tests make refactors harder without improving confidence.
// GOOD: asserts the new behavior this code path introduces
test('adds sentry.trace_lifecycle stream attribute', () async {
final span = fixture.createRecordingSpan();
await fixture.pipeline.captureSpan(span, scope: fixture.scope);
expect(span.attributes[SemanticAttributesConstants.sentryTraceLifecycle]?.value, 'stream');
});
// AVOID in this feature's tests: re-proves that SentryAttribute.string
// stores its value, which is the value object's own contract
test('SentryAttribute.string stores its value', () {
final attribute = SentryAttribute.string('value');
expect(attribute.value, 'value');
});expect() with matchers from package:test.throwsArgumentError, isA<SentryException>()) over generic ones (throwsException, isA<Exception>()).expect() calls are fine if they verify a single behavior.// GOOD: Specific matchers, single logical assertion
test('captures exception with stacktrace', () {
expect(event.exceptions, hasLength(1));
expect(event.exceptions!.first, isA<SentryException>());
expect(event.exceptions!.first.stackTrace, isNotNull);
});
// AVOID: Generic matchers, testing unrelated behaviors
test('captures exception', () {
expect(event.exceptions, isNotNull); // too vague
expect(event.exceptions!.first, isA<Object>()); // too generic
expect(event.breadcrumbs, isEmpty); // unrelated assertion
});// GOOD: pin the expected value as a literal
expect(span.data[SentryDatabase.dbSystemKey], 'sqlite');
// AVOID (tautological): asserting against the same constant the production code uses to set it
expect(span.data[SentryDatabase.dbSystemKey], SentryDatabase.dbSystem);Prefer fakes over mocks — hand-written implementations that capture state, resilient to refactoring and readable as documentation. Reach for a mock only when faking a large third-party interface isn't worth it. A test that's hard to fake usually signals the code under test should accept its dependencies rather than construct them (a design-first concern).
Full guidance, including designing for mockability (dependency injection, SDK-style interfaces, mocking only at real boundaries), in references/mocking.md.
Never fire-and-forget: return the Future or mark the callback async. Use expectLater with stream matchers for streams, and fakeAsync for timer/microtask-dependent code. Examples in references/async.md.
packages/_sentry_testing// GOOD: Deterministic clock
final clock = DateTime.utc(2024, 1, 15, 12, 0, 0);
options.clock = () => clock;
// AVOID: Real clock — flaky on slow CI
final now = DateTime.now();
expect(event.timestamp!.difference(now).inSeconds, lessThan(1));packages/flutter/example/integration_test.© getsentry, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (references) in .agents/skills/test-guidelines of getsentry/sentry-dart.
Open the folder on GitHubat commit 96d6367
Test Guidelines next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Test Guidelines this skillgetsentry/sentry-dart | 873 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Test Guidelinesgetsentry/sentry-react-native | 1.8k | — | ~1.3k | Automated safety check: Pass | MIT | |
| Green GateVeryGoodOpenSource/vgv-ai-flutter-plugin | 169 | — | ~4.7k | Automated safety check: Notes | MIT | |
| Test Driven Developmentaiskillstore/marketplace | 430 | — | ~1.9k | Automated safety check: Pass | None | |
| Flutter TestingMADTeacher/mad-agents-skills | 110 | — | ~1.5k | Automated safety check: Pass | MIT | |
| Testingevanca/flutter-ai-rules | 647 | — | ~1.1k | Automated safety check: Pass | MIT |
getsentry/sentry-react-native
Enforce Sentry React Native SDK test conventions for naming, structure, mocking, and fixtures with Jest.
VeryGoodOpenSource/vgv-ai-flutter-plugin
Drives a Dart or Flutter package fully green through a verify-fix-rerun loop across four gates: analyze, format, test, coverage.
aiskillstore/marketplace
Red-green-refactor development methodology requiring verified test coverage.
MADTeacher/mad-agents-skills
Write, fix, review, debug, and validate Flutter tests for apps, packages, and plugins.
evanca/flutter-ai-rules
A skill your agent uses when writing or reviewing Flutter/Dart tests (unit, widget, golden), fixing flaky tests, adding coverage, or choosing between unit and widget tests.
getsentry/sentry-react-native
Enforce Sentry React Native SDK code guidelines for implementation, refactoring, and review.
getsentry/sentry-dart
Enforce Sentry Dart/Flutter SDK code guidelines for implementation, refactoring, and review.
getsentry/sentry-dart
Shape non-trivial work before writing it — decide the modules, the seams, and the public API surface up front.
getsentry/sentry-dart
Three-axis review of the branch diff — Standards (this repo's documented standards + public API surface), Spec (the originating Linear issue / PR), and Correctness (runtime bugs + the SDK threat…
getsentry/sentry-dart
A discipline for hard bugs, flaky tests, CI hangs, and performance regressions in this SDK.
Categories
Enforce Sentry Dart/Flutter SDK test conventions for naming, structure, and fixtures. Test Guidelines is an agent skill from getsentry/sentry-dart, published by the product's own GitHub organization. Enforce Sentry Dart/Flutter SDK test conventions for naming, structure, and fixtures.
Test Guidelines fits situations like: modifying tests; reviewing test code; fixing failing tests; adding test coverage.
Run `npx skills add getsentry/sentry-dart --skill test-guidelines -a claude-code`. Or copy the skill folder (.agents/skills/test-guidelines in getsentry/sentry-dart) into .claude/skills/test-guidelines in your project. Claude Code loads it when a task matches its description.
Run `npx skills add getsentry/sentry-dart --skill test-guidelines -a codex`. Or copy the skill folder (.agents/skills/test-guidelines in getsentry/sentry-dart) into .agents/skills/test-guidelines in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add getsentry/sentry-dart --skill test-guidelines -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/test-guidelines, .gemini/skills/test-guidelines, .github/skills/test-guidelines and .opencode/skills/test-guidelines in your project.
SKILL.md names no scripts, command-line tools or credentials: Test Guidelines is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Test Guidelines is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.1k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Test Guidelines: Test Guidelines (getsentry/sentry-react-native, 1.8k stars), Green Gate (VeryGoodOpenSource/vgv-ai-flutter-plugin, 169 stars), Test Driven Development (aiskillstore/marketplace, 430 stars) and Flutter Testing (MADTeacher/mad-agents-skills, 110 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
getsentry (a GitHub organization, an official publisher) maintains it in getsentry/sentry-dart, which has 873 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 7, 2026.
Source: getsentry/sentry-dart on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.