# Testing

> Use when writing or reviewing Flutter/Dart tests (unit, widget, golden), fixing flaky tests, adding coverage, or choosing between unit and widget tests.

- **Type:** Skill
- **Install:** `agentstack add skill-evanca-flutter-ai-rules-testing`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [evanca](https://agentstack.voostack.com/s/evanca)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [evanca](https://github.com/evanca)
- **Source:** https://github.com/evanca/flutter-ai-rules/tree/main/skills/testing

## Install

```sh
agentstack add skill-evanca-flutter-ai-rules-testing
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Testing Skill

Write effective, meaningful Flutter and Dart tests that catch real regressions.

## When to Use

Use this skill when:

* Writing unit tests for business logic, repositories, or utility classes.
* Writing widget tests for UI components.
* Reviewing existing tests for correctness and coverage.
* Fixing flaky or false-positive tests.
* Deciding between unit tests, widget tests, and integration tests.

---

## 1. Test Validity

Before writing or accepting a test, ask:

> **"Can this test actually fail if the real code is broken?"**

- Avoid tests that only confirm mocked/fake behavior without exercising real logic.
- Avoid tests that confirm behavior guaranteed by the language or standard library.
- Every test must be capable of catching a real regression.

```dart
// BAD — tests the mock, not real logic
test('should return user', () {
  when(() => repo.getUser()).thenReturn(fakeUser);
  expect(repo.getUser(), fakeUser); // Only proves the mock works
});

// GOOD — tests the cubit's state transitions driven by the mock
blocTest(
  'should emit loaded state when getUser succeeds',
  build: () {
    when(() => repo.getUser()).thenAnswer((_) async => fakeUser);
    return UserCubit(repo);
  },
  act: (cubit) => cubit.fetchUser(),
  expect: () => [
    const UserState(status: UserStatus.loading),
    UserState(status: UserStatus.loaded, user: fakeUser),
  ],
);
```

---

## 2. Structure

Always use `group()` in test files. Name the group after the **class under test**:

```dart
group('Counter', () {
  late Counter counter;

  setUp(() {
    counter = Counter();
  });

  test('value should start at 0', () {
    expect(counter.value, 0);
  });

  test('should increment value by 1', () {
    counter.increment();
    expect(counter.value, 1);
  });
});
```

Rules:
- Use `setUp` for shared object creation; use `tearDown` for cleanup (closing streams, controllers).
- Keep each test focused on one behavior.
- Nest `group()` blocks for sub-features when a class has many methods.

---

## 3. Naming

Name test cases using **"should"** to describe expected behavior:

```dart
test('should emit updated list when item is added', () { ... });
test('should throw ArgumentError when input is negative', () { ... });
```

---

## 4. Unit Tests vs Widget Tests

| Type | Target | Tools |
|---|---|---|
| **Unit test** | Pure Dart logic, repositories, cubits/blocs | `test`, `bloc_test`, `mocktail` |
| **Widget test** | Individual widgets, UI behavior, navigation | `flutter_test`, `WidgetTester` |

Default to **unit tests** for business logic. Use **widget tests** when verifying UI rendering, gesture handling, or widget interaction.

---

## 5. Widget Test Patterns

```dart
testWidgets('should display error message on failure', (tester) async {
  await tester.pumpWidget(
    MaterialApp(
      home: BlocProvider.value(
        value: mockLoginCubit,
        child: const LoginView(),
      ),
    ),
  );

  // Simulate failure state
  whenListen(
    mockLoginCubit,
    Stream.fromIterable([const LoginState(status: LoginStatus.failure, errorMessage: 'Invalid')]),
    initialState: const LoginState(),
  );
  await tester.pump();

  expect(find.text('Invalid'), findsOneWidget);
});
```

Rules:
- Wrap widgets in `MaterialApp` (or the app's root widget) to provide `MediaQuery`, `Directionality`, etc.
- Use `pump()` for a single frame or `pumpAndSettle()` when animations must complete.
- Prefer `find.byKey` over `find.text` for widgets that may have localized or dynamic text.

---

## 6. Mocking Best Practices

- Use `mocktail` for mocks (no code generation required).
- Call `registerFallbackValue()` in `setUpAll` for custom types passed to `any()`.
- Mock at the repository boundary, not at the HTTP/database layer.

```dart
class MockAuthRepository extends Mock implements AuthRepository {}

void main() {
  setUpAll(() {
    registerFallbackValue(FakeLoginRequest());
  });

  // ... tests
}
```

---

## 7. Test File Organization

```
test/
  feature_a/
    cubit/
      feature_a_cubit_test.dart
    view/
      feature_a_view_test.dart
    model/
      feature_a_model_test.dart
```

- Mirror the `lib/` folder structure under `test/`.
- One test file per source file.
- Name test files `_test.dart`.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [evanca](https://github.com/evanca)
- **Source:** [evanca/flutter-ai-rules](https://github.com/evanca/flutter-ai-rules)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-evanca-flutter-ai-rules-testing
- Seller: https://agentstack.voostack.com/s/evanca
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
