Skip to main content
Since patrol_finders is a separate package, you can use it in your widget or golden tests without depending on the full patrol package.

Installation

1

Add the dependency

Add the patrol_finders package as a dev_dependency in your app’s pubspec.yaml:
flutter pub add patrol_finders --dev
This will add the following to your pubspec.yaml:
pubspec.yaml
dev_dependencies:
  patrol_finders: ^4.0.0
2

Import in your test files

Import patrol_finders in your test files:
test/widget_test.dart
import 'package:patrol_finders/patrol_finders.dart';
This import gives you access to the $ syntax, PatrolTester, and patrolWidgetTest().
3

Write your first test

You can now use Patrol finders in your tests!

Two Ways to Use Patrol Finders

There are two approaches to using Patrol finders in your tests: The patrolWidgetTest() function is a drop-in replacement for testWidgets() that automatically creates a PatrolTester for you:
test/patrol_widget_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol_finders/patrol_finders.dart';

void main() {
  patrolWidgetTest(
    'counter is decremented when minus button is tapped',
    (PatrolTester $) async {
      await $.pumpWidget(const MyApp());

      expect($('0'), findsOneWidget);
      expect($('-1'), findsNothing);

      await $(Icons.remove).tap();

      expect($('0'), findsNothing);
      expect($('-1'), findsOneWidget);
    },
  );
}
By convention, we name the PatrolTester parameter $ to keep test code concise and readable.

Option 2: Manual PatrolTester Creation

If you need more control, you can manually create a PatrolTester inside a regular testWidgets() call:
test/widget_test_with_patrol_finders.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol_finders/patrol_finders.dart';

void main() {
  testWidgets(
    'counter is decremented when minus button is tapped',
    (WidgetTester tester) async {
      PatrolTester $ = PatrolTester(
        tester: tester,
        config: PatrolTesterConfig(),
      );
      
      await $.pumpWidget(const MyApp());

      expect($('0'), findsOneWidget);
      expect($('-1'), findsNothing);

      await $(Icons.remove).tap();

      expect($('0'), findsNothing);
      expect($('-1'), findsOneWidget);
    },
  );
}

Configuration

You can customize Patrol’s behavior using PatrolTesterConfig:
patrolWidgetTest(
  'logs in successfully',
  config: PatrolTesterConfig(
    // How long to wait for widgets to become visible
    visibleTimeout: Duration(seconds: 20),
    
    // How long to wait for widgets to exist
    existsTimeout: Duration(seconds: 10),
    
    // Timeout for pumpAndSettle operations
    settleTimeout: Duration(seconds: 10),
    
    // Default settle policy for actions
    settlePolicy: SettlePolicy.trySettle,
    
    // Duration for drag gestures during scrolling
    dragDuration: Duration(milliseconds: 100),
    
    // Timeout for settling between scroll gestures
    settleBetweenScrollsTimeout: Duration(seconds: 5),
    
    // Enable logging (useful for debugging)
    printLogs: true,
  ),
  ($) async {
    // Your test code
  },
);
patrolWidgetTest(
  'waits for slow loading widget',
  config: PatrolTesterConfig(
    visibleTimeout: Duration(seconds: 30),
  ),
  ($) async {
    await $.pumpWidget(const MyApp());
    await $('Loaded content').waitUntilVisible();
  },
);

Running Your Tests

Run your tests using the standard Flutter test command:
flutter test
Or run a specific test file:
flutter test test/widget_test.dart

Next Steps

Learn Basic Usage

Discover how to find widgets, make assertions, and perform actions

Explore Advanced Features

Master complex scenarios and advanced techniques