Dart Lifecycle Disposed Flag Overload
divinevideo/divine-mobile
Fix Dart/Flutter services where calling start() after stop() is a silent no-op because stop() sets a disposed (or similar) flag that start()'s guard short-circuits on.
Best practices for Dart unit tests, Flutter widget tests, and golden file tests, covering group and test naming, setUp lifecycle and isolation, mocking with package:mocktail, and the shared pumpApp…
$ npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin testing --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/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/testing .claude/skills/testing && 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 "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .claude/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testingType 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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/testing .agents/skills/testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .agents/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/testing .cursor/skills/testing && 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 "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .cursor/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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/VeryGoodOpenSource/vgv-ai-flutter-plugin.git --path skills/testing--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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/testing .gemini/skills/testing && 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 "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .gemini/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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 VeryGoodOpenSource/vgv-ai-flutter-plugin testingInstalls 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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/testing .github/skills/testing && 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 "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .github/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install VeryGoodOpenSource/vgv-ai-flutter-plugin testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/testing .opencode/skills/testing && 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 "testing" agent skill from https://github.com/VeryGoodOpenSource/vgv-ai-flutter-plugin/tree/main/skills/testing into .opencode/skills/testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "testing", 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.
testingBest practices for Dart unit tests, Flutter widget tests, and golden file tests, covering group and test naming, setUp lifecycle and isolation, mocking with package:mocktail, and the shared pumpApp…
Testing is an agent skill from VeryGoodOpenSource/vgv-ai-flutter-plugin. Best practices for Dart unit tests, Flutter widget tests, and golden file tests, covering group and test naming, setUp lifecycle and isolation, mocking with package:mocktail, and the shared pumpApp helper. Use when writing, modifying, or reviewing tests, goldens included, that use package:test, package:fluttertest, package:mocktail, or package:bloctest, and when no package is named: adding a golden test, matchesGoldenFile, tagging or updating goldens, writing a unit or widget test, or adding a test helper or…
Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 11 other files, including reference files (for example `agents/openai.yaml`, `references/animation-testing.md` and `references/configuration.md`).
It sits in Mobile, covering Cross-platform mobile apps and Unit testing. It works with Flutter and Dart. The repository describes itself as: AI plugin to enhance and accelerate Flutter & Dart development, built by Very Good Ventures. The licence is MIT.
Read from SKILL.md and the folder at commit 496a3c6. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadGlobGrepmcp__very-good-cli__testFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
flutterdartFrom 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.
Testing loads about 3.2k tokens when it runs, and up to ~10k if it reads all its reference files. Until then it costs about 228 tokens; SKILL.md has 946 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 VeryGoodOpenSource/vgv-ai-flutter-plugin at commit 496a3c6, republished under its MIT licence (© VeryGoodOpenSource). 946 words, ~3,152 tokens.
.claude/skills/testing/SKILL.md (or your agent's skills folder). This skill also uses 9 other files; get the full folder from GitHub.VGV testing conventions for Dart and Flutter. The framework APIs are assumed; what follows is the house style layered on top of them.
Apply these standards to all test work:
'works' or 'renders'group for the class, nested group for the method, test for the behavior (e.g., UserRepository → getUser → returns User when API succeeds)'returns $User' not 'returns User' so renames propagate automaticallyclass _MockX extends Mock implements X {} with underscore prefix to prevent cross-file couplingsetUp/tearDown calls live inside a group, never at the top level of main()setUp() with late — declare late MyDep dep; then assign in setUp so each test gets a fresh instancepackage:mocktail — never package:mockitoabstract class TestTag with static const fields; never pass raw string literals as tagspumpApp test helper — wrap widgets via shared helper in test/helpers/pump_app.dart; never inline pumpWidget(MaterialApp(...))TestTag.golden so goldens can run/update independentlydirectory to the test MCP tool when the project is not at the workspace root — monorepos with the Flutter project in a subdirectory (e.g. mobile/) require directory: 'mobile'; omit it only when pubspec.yaml is at the workspace roottimeout_seconds to the test MCP tool — Flutter tests can hang indefinitely when pumpAndSettle() is called without a timeout; set a cap (e.g. timeout_seconds: 120) so the run is killed instead of stallingtest MCP tool — on Claude Code use mcp__very-good-cli__test; on a host without this plugin's Bash hooks and without that MCP server connected, run very_good test (or flutter test / dart test) directly with the same coverage and timeout options — never block on a missing MCP server| Convention | Rule |
|---|---|
| File suffix | Every test file ends with _test.dart |
| Directory | All tests live under test/ |
| Mirror structure | test/ mirrors lib/ exactly — lib/src/models/user.dart → test/src/models/user_test.dart |
| Helpers | Shared test utilities go in test/helpers/ (e.g., pump_app.dart, fakes.dart) |
Structure groups so that concatenated descriptions read as natural sentences. Use the
PascalCase type itself — not a string — in the top-level group.
class _MockApiClient extends Mock implements ApiClient {}
void main() {
group(UserRepository, () {
late ApiClient apiClient;
late UserRepository subject;
setUp(() {
apiClient = _MockApiClient();
subject = UserRepository(apiClient: apiClient);
});
group('getUser', () {
test('returns $User when API call succeeds', () async {
when(() => apiClient.fetchUser(any()))
.thenAnswer((_) async => User(id: '1', name: 'Dash'));
final result = await subject.getUser('1');
expect(result, equals(User(id: '1', name: 'Dash')));
verify(() => apiClient.fetchUser('1')).called(1);
});
test('throws $UserNotFoundException when API returns 404', () {
when(() => apiClient.fetchUser(any()))
.thenThrow(ApiException(statusCode: 404));
expect(
() => subject.getUser('1'),
throwsA(isA<UserNotFoundException>()),
);
});
});
});
}| Pattern | Example |
|---|---|
| Returns a value | 'returns $User when API call succeeds' |
| Throws an exception | 'throws $UserNotFoundException when user is not found' |
| Calls a dependency | 'calls apiClient.deleteUser with correct id' |
| Emits states | 'emits [loading, success] when data is fetched' |
| Conditional behavior | 'returns cached value when cache is not expired' |
| Edge case | 'returns empty list when repository has no items' |
Each test must pass when run individually, in any order, and in parallel. Use
--test-randomize-ordering-seed random to expose hidden dependencies.
| Anti-Pattern | Problem | Correct Approach |
|---|---|---|
setUp at the top level of main() | Breaks when test runner merges files for optimization | Move setUp inside a group |
final dep = _MockDep(); (top-level) | Same instance shared across all tests; state leaks | Use late + setUp inside a group |
class MockDep extends Mock (public) | Other test files can import and depend on it | Use class _MockDep extends Mock (private) |
| Static/global mutable variables | State persists across tests | Reset in setUp or avoid entirely |
| Tests that must run in a specific order | Fragile, fails with random ordering | Make each test fully self-contained |
Never test private methods directly. Exercise private logic through the public method that uses it:
// If _normalizeEmail is private, test it through the public createUser method:
test('normalizes email to lowercase before saving', () async {
when(() => repository.save(any())).thenAnswer((_) async {});
await subject.createUser(email: 'Dash@Example.COM');
final captured = verify(() => repository.save(captureAny())).captured;
expect(captured.first.email, equals('dash@example.com'));
});| Rule | Details |
|---|---|
Use testWidgets | Every widget test uses testWidgets instead of test |
Prefer find.byType | Default finder; use find.text for user-visible content, find.byKey only when type/text is ambiguous |
| Group by behavior category | Use renders, navigates, calls [MethodName], updates as nested group names |
| Focus on behavior | Assert what the widget does (shows text, calls callback, navigates); use golden tests for visual appearance |
| Mock Blocs and Cubits | Use MockBloc/MockCubit from package:bloc_test; never provide real Blocs in widget tests |
Prefer pump() over pumpAndSettle() | pumpAndSettle hangs on infinite animations such as CircularProgressIndicator |
Every widget test wraps the widget under test through one shared helper, so no test
inlines its own MaterialApp:
// test/helpers/pump_app.dart
extension PumpApp on WidgetTester {
Future<void> pumpApp(Widget widget) {
return pumpWidget(
MaterialApp(
home: widget,
),
);
}
}Export it from test/helpers/helpers.dart so every test imports it with one line:
import '../helpers/helpers.dart';
void main() {
group(MyWidget, () {
testWidgets('renders greeting text', (tester) async {
await tester.pumpApp(const MyWidget());
expect(find.text('Hello'), findsOneWidget);
});
});
}| Anti-Pattern | Problem | Correct Approach |
|---|---|---|
Inline MaterialApp in each test | Duplicated boilerplate; inconsistent setup | Use pumpApp helper |
find.byKey as default finder | Couples tests to implementation keys | Prefer find.byType or find.text |
| Testing padding, colors, or font sizes | Fragile; breaks on every design tweak; asserts appearance, not behavior | Use a golden test for visual validation |
Missing pump() after interaction | Widget tree does not rebuild; assertion sees stale state | Always pump() after tap, enterText, etc. |
| Real Blocs in widget tests | Tests become integration tests; slow, brittle, hard to isolate | Use MockBloc/MockCubit from bloc_test |
Padding, background color, and font size are the recurring temptation. Asserting them in a
widget test couples the test to the design system and breaks on every restyle — move them to
a golden test tagged TestTag.golden.
setUp/tearDown lifecycle and patterns for async, streams, exceptions, Equatable, and callbackspumpApp, pumping methods, finders, and interactionsdart_test.yaml configuration (tags, platform overrides) and running tests via the MCP test tool© VeryGoodOpenSource, 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 9 other files (references) in skills/testing of VeryGoodOpenSource/vgv-ai-flutter-plugin.
Open the folder on GitHubat commit 496a3c6
Testing 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 |
|---|---|---|---|---|---|---|
| Testing this skillVeryGoodOpenSource/vgv-ai-flutter-plugin | 170 | — | ~3.2k | Automated safety check: Pass | MIT | |
| Dart Lifecycle Disposed Flag Overloaddivinevideo/divine-mobile | 266 | — | ~2k | Automated safety check: Pass | MPL-2.0 | |
| Flutter TestingMADTeacher/mad-agents-skills | 110 | — | ~1.5k | Automated safety check: Pass | MIT | |
| Testingevanca/flutter-ai-rules | 650 | — | ~1.1k | Automated safety check: Pass | MIT | |
| Native Testing Strategybladeofgod/flutter-ai-harness | 116 | — | ~345 | Automated safety check: Pass | MIT | |
| Flutter TesterFNOSP/FlyNarwhal | 496 | — | ~1.4k | Automated safety check: Pass | AGPL-3.0 |
divinevideo/divine-mobile
Fix Dart/Flutter services where calling start() after stop() is a silent no-op because stop() sets a disposed (or similar) flag that start()'s guard short-circuits on.
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.
bladeofgod/flutter-ai-harness
适用:设计或审查 Kotlin/Swift 原生模块、Bridge Adapter、Host 编译、模拟器/设备和系统能力验证。不适用:纯 Dart/Flutter 测试或用 Fake 代替相机和权限真机验证。触发词:JUnit、XCTest、Robolectric、instrumented test、Swift Testing、Framework Fake、Gradle…
FNOSP/FlyNarwhal
A skill your agent uses when creating, writing, fixing, or reviewing tests in a Flutter project.
Arenukvern/mcp_flutter
A skill your agent uses when writing or running repeatable E2E scenarios for Flutter apps as checked-in Dart with the fluttermcpharness package (packages/harness) — build/launch the app, attach to…
VeryGoodOpenSource/vgv-ai-flutter-plugin
Audits or remediates Flutter widgets against WCAG 2.2 conformance levels A, AA, or AAA across iOS, Android, Web, macOS, Windows, and Linux, covering Semantics labels and screen reader output under…
VeryGoodOpenSource/vgv-ai-flutter-plugin
Best practices for Flutter animations using the built-in animation framework, covering implicit animations, explicit AnimationController animations, page transitions, and Material 3 motion tokens.
VeryGoodOpenSource/vgv-ai-flutter-plugin
Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder…
VeryGoodOpenSource/vgv-ai-flutter-plugin
VGV-specific reference for bumping Dart and Flutter SDK constraints across packages, covering pubspec.yaml environment constraints, CI workflow Flutter versions, and SDK upgrade PR preparation.
VeryGoodOpenSource/vgv-ai-flutter-plugin
Best practices for internationalization (i18n) and localization (l10n) in Flutter, using the built-in flutterlocalizations and intl setup with ARB files as the single source of truth.
VeryGoodOpenSource/vgv-ai-flutter-plugin
VGV layered monorepo architecture in Flutter: four layers Data, Repository, Business Logic, and Presentation, unidirectional dependency rules, and model transformation across layers.
Categories
Best practices for Dart unit tests, Flutter widget tests, and golden file tests, covering group and test naming, setUp lifecycle and isolation, mocking with package:mocktail, and the shared pumpApp…. Testing is an agent skill from VeryGoodOpenSource/vgv-ai-flutter-plugin. Best practices for Dart unit tests, Flutter widget tests, and golden file tests, covering group and test naming, setUp lifecycle and isolation, mocking with package:mocktail, and the shared pumpApp helper.
Testing fits situations like: reviewing tests; goldens included; that use package:test; package:fluttertest.
Run `npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a claude-code`. Or copy the skill folder (skills/testing in VeryGoodOpenSource/vgv-ai-flutter-plugin) into .claude/skills/testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a codex`. Or copy the skill folder (skills/testing in VeryGoodOpenSource/vgv-ai-flutter-plugin) into .agents/skills/testing 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 VeryGoodOpenSource/vgv-ai-flutter-plugin --skill testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/testing, .gemini/skills/testing, .github/skills/testing and .opencode/skills/testing in your project.
Going by SKILL.md and its folder, Testing needs the command-line tools its instructions call (flutter and dart). Its frontmatter pre-approves these tools: Read, Glob, Grep, mcp__very-good-cli__test.
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.
Testing 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.2k 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 6.9k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Testing: Dart Lifecycle Disposed Flag Overload (divinevideo/divine-mobile, 266 stars), Flutter Testing (MADTeacher/mad-agents-skills, 110 stars), Testing (evanca/flutter-ai-rules, 650 stars) and Native Testing Strategy (bladeofgod/flutter-ai-harness, 116 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
VeryGoodOpenSource (a GitHub organization) maintains it in VeryGoodOpenSource/vgv-ai-flutter-plugin, which has 170 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on October 6, 2026.
Source: VeryGoodOpenSource/vgv-ai-flutter-plugin on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.