Robot Testing
Write stable, maintainable Flutter widget tests using the robot testing pattern. The /flutter-robot-testing skill generates tests that use key-based selectors, dependency injection, and deterministic fakes.
Scenario
Section titled “Scenario”You have a multi-step user flow (e.g., sign-in, browse products, add to cart, checkout) and you want widget tests that verify the entire journey without relying on fragile finders like find.text('Submit').
Prerequisites
Section titled “Prerequisites”- ACT Pro installed and verified (
/act:help) - A Flutter project with at least one user-facing screen implemented
- Widget keys defined on interactive elements (buttons, text fields, etc.)
- Familiarity with Flutter widget testing basics
What robot testing solves
Section titled “What robot testing solves”Standard widget tests mix finder logic, interaction steps, and assertions into a single function. This makes them brittle and hard to read. The robot pattern extracts interactions into a robot class that reads like a user story:
final r = SignInRobot(tester);await r.enterEmail('user@example.com');await r.enterPassword('password123');await r.tapSignInButton();r.expectDashboardVisible();1. Start the robot testing skill
Section titled “1. Start the robot testing skill”/flutter-robot-testingThe skill loads robot testing rules covering key-first selectors, DI/fake setup, and risk reporting conventions.
2. Describe the user journey
Section titled “2. Describe the user journey”Tell the AI which flow to test:
"Test the sign-in flow: enter email, enter password, tap sign in, verify dashboard appears"3. Set up test seams with dependency injection
Section titled “3. Set up test seams with dependency injection”The AI creates (or reuses) fakes for external dependencies:
class FakeAuthRepository extends Fake implements AuthRepository { @override Future<User> signIn(String email, String password) async { return User(id: '1', email: email); }}These fakes are injected via your app’s DI system (Provider, Riverpod, get_it, etc.) so the test never hits real services.
4. Generate the robot class
Section titled “4. Generate the robot class”The AI creates a robot class with methods for each interaction step:
class SignInRobot { SignInRobot(this.tester); final WidgetTester tester;
Future<void> enterEmail(String email) async { final field = find.byKey(const Key('signInEmailField')); await tester.enterText(field, email); await tester.pump(); }
Future<void> tapSignInButton() async { final button = find.byKey(const Key('signInButton')); await tester.tap(button); await tester.pumpAndSettle(); }
void expectDashboardVisible() { expect(find.byKey(const Key('dashboardScreen')), findsOneWidget); }}All finders use find.byKey for stability. No find.text or find.byType for interactive elements.
5. Write the test using the robot
Section titled “5. Write the test using the robot”testWidgets('sign in navigates to dashboard', (tester) async { await tester.pumpWidget(makeTestApp( authRepository: FakeAuthRepository(), ));
final r = SignInRobot(tester); await r.enterEmail('user@example.com'); await r.enterPassword('password123'); await r.tapSignInButton(); r.expectDashboardVisible();});6. Run and verify
Section titled “6. Run and verify”The AI runs flutter test to confirm the test passes, then reports any risks or coverage gaps it identified during generation.
7. Extend to additional journeys
Section titled “7. Extend to additional journeys”Add more test cases for the same flow (invalid credentials, empty fields, network errors) and extend to other user journeys by creating new robot classes.
Expected output
Section titled “Expected output”- One robot class per screen or flow under test
- Widget tests that read like user stories
- All finders using stable key-based selectors
- Fakes for all external dependencies (no real network calls, no real databases)
flutter testpassing with the new tests
Common pitfalls
Section titled “Common pitfalls”- Missing widget keys — If your widgets do not have keys, the AI will flag this. Add keys to interactive elements before generating robot tests.
- Using
find.textfor buttons — Text changes break tests. Always usefind.byKeyfor elements users interact with. - Testing implementation details — Robot tests should verify user-visible outcomes, not internal state. Check what the user sees, not what the repository stores.
- Non-deterministic fakes — Fakes must return consistent results. Avoid random data or timestamps in test fakes.
Next steps
Section titled “Next steps”- Pair robot testing with the Test-Driven Development playbook to build features test-first
- Use the Screenshot Verification playbook to visually confirm UI matches expectations
- See
/act:workflow:workfor how robot tests integrate into the automated work phase