testing-strategy

Enforces Flutter test doctrine with fuzz tests, in-memory Drift, and headless Notifier harnesses.

Updated Aug 22, 2026
One-click install
npx skills add https://github.com/zakariaf/NearlyStop --skill testing-strategy-zakariaf
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: testing-strategy
Source: https://github.com/zakariaf/NearlyStop/tree/main/.claude/skills/testing-strategy
Command: npx skills add https://github.com/zakariaf/NearlyStop --skill testing-strategy-zakariaf

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Flutter test suites often follow an outdated pyramid ratio, mock away the database, and leak wall-clock time into domain logic, producing slow, flaky tests that prove nothing about real behavior. This Skill defines a concrete test doctrine: test each behavior at the cheapest tier that can assert it, and make every test a build-pass/fail signal. ## Core Features & Use Cases - Layered test harnesses: Per-layer patterns for pure Dart domain packages (package:test, injected Clock), in-memory Drift databases (NativeDatabase.memory), headless Riverpod Notifiers via ProviderContainer, and integration tests. - Property and fuzz testing: Seeded fuzz loops against independent oracles, round-trip conversion tests, rounding goldens, and absence-of-a-failure-class assertions over enum-driven fake environments. - Fakes over mocks: Bare-implements fakes for owned interfaces, mocktail reserved for external dependencies with registerFallbackValue discipline, and grep-based hygiene scripts that ban DateTime.now(), mocked DAOs, pumpAndSettle, and mockito. - Coverage governance: File-level 100% floors on unrecoverable-bug files (migrations, money allocation, wire-format parsers), the coverage-lies-upward fix, suite-time budgets, and a named manual pre-release pass for structurally untestable paths. - Use Case: When adding a new feature with a Drift table and a Riverpod Notifier, use this Skill to write a real in-memory database test proving the CHECK constraint, a headless ProviderContainer test driving the Notifier, and a seeded fuzz test for any allocation math. ## Quick Start Ask the AI to write tests for a new Flutter feature following the testing-strategy doctrine, choosing the cheapest test tier per behavior.

Frequently Asked Questions about testing-strategy

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I test Flutter Riverpod Notifiers without widgets?▼

Drive Notifiers headlessly with a ProviderContainer, overriding dependencies via overrideWith and asserting on the exposed AsyncValue state. Dispose the container in teardown, or use ProviderContainer.test() on Riverpod 3.x for automatic disposal.

Should I mock my Drift DAO in Flutter tests?▼

No, test the data layer against a real NativeDatabase.memory() instance instead of a mocked DAO. A mocked DAO proves nothing about SQL, constraints, indexes, or migrations; only mock repositories above the data layer.

When should I use fakes vs mocktail in Dart tests?▼

Use bare-implements fakes for interfaces your repo owns, since interface changes become compile errors and the fake documents the contract. Reserve mocktail for genuinely external dependencies, and register a fallback value for every custom type passed to any().

How do I test time-dependent Dart logic deterministically?▼

Inject package:clock's Clock into domain logic and pin it in tests with withClock(Clock.fixed(t), ...). Never call DateTime.now() from domain code, since ambient wall-clock time makes identical inputs produce different outputs.

Why does pumpAndSettle hang in Flutter widget tests?▼

pumpAndSettle() waits for all animations to finish, so it hangs on indefinite animations like spinners or shimmer until the 10-minute timeout. Use timed pump(Duration) calls with fakeAsync instead.

Why does flutter test coverage overstate actual coverage?▼

flutter test --coverage omits files that no test imports, so untested files contribute zero lines to the denominator and the percentage lies upward. Fix it with dlcov --include-untested-files=true or a generated helper test importing every file under lib/.