flutter_test_helpers 0.0.6 copy "flutter_test_helpers: ^0.0.6" to clipboard
flutter_test_helpers: ^0.0.6 copied to clipboard

Comprehensive Flutter testing toolkit with mock data generators, visual regression testing, performance testing, and screenshot testing utilities.

flutter_test_helpers #

Pub Version Flutter Version Dart Version Platform Support WASM Compatible

A comprehensive Flutter package providing mock data generators, test utilities, and widget testing helpers to streamline your Flutter testing workflow.

Features #

  • 🎲 Mock Data Generators: Generate random test data for colors, strings, numbers, dates, and more
  • πŸ§ͺ Test Utilities: Helper functions for common testing scenarios
  • 🎯 Widget Testing Helpers: Extensions and utilities for widget testing
  • πŸ”§ Extensions: Useful extensions for common Flutter types (Color, String, DateTime, List)
  • πŸ“Έ Visual Regression Testing: Compare widgets with golden files for visual consistency
  • ⚑ Performance Testing: Measure widget performance, frame times, and memory usage
  • πŸ“· Screenshot Testing: Capture and save screenshots for documentation and testing
  • 🌍 Multi-Platform Support: Supports all 6 platforms (iOS, Android, Web, Windows, macOS, Linux)
  • ⚑ WASM Compatible: Ready for Flutter WebAssembly
  • πŸ“± Flutter 3.10+: Built with the latest Flutter features

Getting Started #

Installation #

Add flutter_test_helpers to your pubspec.yaml:

dependencies:
  flutter_test_helpers: ^0.0.6

Import #

import 'package:flutter_test_helpers/flutter_test_helpers.dart';

Usage #

Mock Data Generators #

Generate random test data for your tests:

// Generate random colors
final color = MockDataGenerators.randomColor();
final colorList = MockDataGenerators.randomColorList(5);

// Generate random strings
final string = MockDataGenerators.randomString(15);
final stringList = MockDataGenerators.randomStringList(3);

// Generate random numbers
final intValue = MockDataGenerators.randomInt(1, 100);
final doubleValue = MockDataGenerators.randomDouble(0.0, 1.0);

// Generate random dates
final date = MockDataGenerators.randomDate();

// Generate random booleans
final boolValue = MockDataGenerators.randomBool();

Test Utilities #

Create test apps and wait for conditions:

// Create a test app
final app = TestUtilities.createTestApp(MyWidget());
final themedApp = TestUtilities.createTestAppWithTheme(MyWidget(), myTheme);

// Wait for conditions
await TestUtilities.waitForCondition(() => someCondition);

// Find widgets
final finder = TestUtilities.findByKey(Key('my-key'));
final textFinder = TestUtilities.findByText('Hello World');

// Interact with widgets
await TestUtilities.tap(tester, finder);
await TestUtilities.enterText(tester, finder, 'New Text');
await TestUtilities.scrollTo(tester, finder);

Widget Testing Helpers #

Create specialized test widgets:

// Create padded widget
final paddedWidget = WidgetTestingHelpers.createPaddedWidget(
  MyWidget(),
  padding: EdgeInsets.all(16.0),
);

// Create constrained widget
final constrainedWidget = WidgetTestingHelpers.createConstrainedWidget(
  MyWidget(),
  maxWidth: 300,
  maxHeight: 200,
);

// Create themed widget
final themedWidget = WidgetTestingHelpers.createThemedWidget(
  MyWidget(),
  theme: ThemeData(primarySwatch: Colors.blue),
);

// Create localized widget
final localizedWidget = WidgetTestingHelpers.createLocalizedWidget(
  MyWidget(),
  locale: Locale('en', 'US'),
);

// Create media query widget
final mediaQueryWidget = WidgetTestingHelpers.createMediaQueryWidget(
  MyWidget(),
  screenSize: Size(800, 600),
  devicePixelRatio: 2.0,
);

Extensions #

Use helpful extensions on common Flutter types:

// Color extensions
final lighterColor = Colors.blue.lighten(0.2);
final darkerColor = Colors.blue.darken(0.2);
final contrastColor = Colors.blue.contrastColor;
final hexString = Colors.red.toHex();

// String extensions
final capitalized = 'hello'.capitalize; // 'Hello'
final titleCase = 'hello world'.titleCase; // 'Hello World'
final truncated = 'long text'.truncate(5); // 'lo...'
final isValidEmail = 'test@example.com'.isEmail; // true

// DateTime extensions
final isToday = someDate.isToday;
final startOfDay = someDate.startOfDay;
final relativeTime = someDate.relativeTime; // '2 hours ago'

// List extensions
final randomElement = [1, 2, 3, 4, 5].random;
final shuffled = [1, 2, 3, 4, 5].shuffled;
final firstOrNull = [].firstOrNull; // null

WidgetTester Extensions #

Use convenient extensions on WidgetTester:

// Tap by key, text, or type
await tester.tapByKey(Key('my-button'));
await tester.tapByText('Click me');
await tester.tapByType<ElevatedButton>();

// Enter text by key or type
await tester.enterTextByKey(Key('my-field'), 'Hello');
await tester.enterTextByType<TextField>('World');

// Scroll to widgets
await tester.scrollToKey(Key('my-widget'));
await tester.scrollToText('Hidden text');

// Wait for widgets
await tester.waitForWidget(find.byType(MyWidget));
await tester.waitForWidgetToDisappear(find.byType(LoadingWidget));

Finder Extensions #

Use helpful extensions on Finder:

// Check finder state
if (finder.hasOne) {
  // Exactly one widget found
}
if (finder.hasMultiple) {
  // Multiple widgets found
}

// Get widgets and elements
final widget = finder.firstWidget;
final allWidgets = finder.allWidgets;
final element = finder.firstElement;
final allElements = finder.allElements;

Visual Regression Testing #

Compare widgets with golden files for visual consistency:

// Basic visual regression test
await VisualRegressionTesting.expectWidgetMatchesGolden(
  tester,
  MyWidget(),
  goldenName: 'my_widget_golden',
);

// With custom configuration
final config = VisualRegressionConfig(
  pixelDifferenceThreshold: 0.01,
  updateGoldens: false,
  screenSize: Size(375, 812),
);

await VisualRegressionTesting.expectWidgetMatchesGolden(
  tester,
  MyWidget(),
  goldenName: 'my_widget_golden',
  config: config,
);

// Create visual test widgets
final testWidget = VisualRegressionTesting.createVisualTestWidget(
  MyWidget(),
  theme: ThemeData(useMaterial3: true),
);

// Multi-theme testing
final multiThemeWidget = VisualRegressionTesting.createMultiThemeTestWidget(
  MyWidget(),
  themes: [lightTheme, darkTheme],
);

// Responsive testing
final responsiveWidget = VisualRegressionTesting.createResponsiveTestWidget(
  MyWidget(),
  screenSizes: [Size(375, 812), Size(768, 1024)],
);

Performance Testing #

Measure widget performance, frame times, and memory usage:

// Measure widget performance
final metrics = await PerformanceTesting.measureWidgetPerformance(
  tester,
  MyWidget(),
);
print('FPS: ${metrics.fps}');
print('Average frame time: ${metrics.averageFrameTimeMs}ms');
print('Meets requirements: ${metrics.meetsRequirements}');

// Measure action performance
final actionMetrics = await PerformanceTesting.measureActionPerformance(
  tester,
  () async {
    await tester.tap(find.byKey(Key('button')));
    await tester.pumpAndSettle();
  },
);

// Measure scroll performance
final scrollMetrics = await PerformanceTesting.measureScrollPerformance(
  tester,
  SingleChildScrollView(child: MyWidget()),
  scrollDistance: 1000.0,
);

// Measure animation performance
final animationMetrics = await PerformanceTesting.measureAnimationPerformance(
  tester,
  AnimatedContainer(
    duration: Duration(seconds: 1),
    child: MyWidget(),
  ),
);

// Custom performance configuration
final config = PerformanceConfig(
  maxFrameTimeMs: 16.67, // 60 FPS
  maxFrames: 100,
  warmUpDuration: Duration(seconds: 1),
  measurementDuration: Duration(seconds: 3),
  trackMemory: true,
);

final metrics = await PerformanceTesting.measureWidgetPerformance(
  tester,
  MyWidget(),
  config: config,
);

Screenshot Testing #

Capture and save screenshots for documentation and testing:

// Take screenshot of widget
final screenshot = await ScreenshotTesting.takeScreenshot(
  tester,
  MyWidget(),
);

// Take screenshot and save to file
final file = await ScreenshotTesting.takeScreenshotAndSave(
  tester,
  MyWidget(),
  filename: 'my_widget_screenshot',
);

// Take current screenshot
final currentScreenshot = await ScreenshotTesting.takeCurrentScreenshot(tester);

// Responsive screenshots
final files = await ScreenshotTesting.takeResponsiveScreenshots(
  tester,
  MyWidget(),
  screenSizes: [
    Size(375, 812),  // iPhone
    Size(768, 1024), // iPad
    Size(1920, 1080), // Desktop
  ],
  baseFilename: 'my_widget_responsive',
);

// Themed screenshots
final themedFiles = await ScreenshotTesting.takeThemedScreenshots(
  tester,
  MyWidget(),
  themes: [lightTheme, darkTheme],
  baseFilename: 'my_widget_themed',
);

// Device frame screenshots
final deviceFrameWidget = ScreenshotTesting.createDeviceFrameWidget(
  MyWidget(),
  deviceType: DeviceType.iphone,
);

// Custom screenshot configuration
final config = ScreenshotConfig(
  screenshotDirectory: 'test/screenshots',
  imageFormat: ImageFormat.png,
  devicePixelRatio: 3.0,
  screenSize: Size(375, 812),
  includeDeviceFrame: true,
  backgroundColor: Colors.white,
  waitForAnimations: true,
);

Creating Extension Methods #

To use the testing utilities with convenient extension methods on WidgetTester, create a file in your test directory:

// test/test_extensions.dart
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_test_helpers/flutter_test_helpers.dart';

/// Extension methods for easier performance testing
extension PerformanceTestingExtension on WidgetTester {
  Future<PerformanceMetrics> measureWidgetPerformance(
    Widget widget, {
    PerformanceConfig? config,
  }) async {
    return PerformanceTesting.measureWidgetPerformance(this, widget, config: config);
  }
}

/// Extension methods for easier screenshot testing
extension ScreenshotTestingExtension on WidgetTester {
  Future<Uint8List> takeScreenshot(Widget widget, {ScreenshotConfig? config}) async {
    return ScreenshotTesting.takeScreenshot(this, widget, config: config);
  }
}

/// Extension methods for easier visual regression testing
extension VisualRegressionTestingExtension on WidgetTester {
  Future<void> expectWidgetMatchesGolden(
    Widget widget, {
    required String goldenName,
    VisualRegressionConfig? config,
  }) async {
    await VisualRegressionTesting.expectWidgetMatchesGolden(
      this,
      widget,
      goldenName: goldenName,
      config: config,
    );
  }
}

Then import this file in your test files:

import 'test_extensions.dart';

// Now you can use extension methods
await tester.measureWidgetPerformance(MyWidget());
await tester.takeScreenshot(MyWidget());
await tester.expectWidgetMatchesGolden(MyWidget(), goldenName: 'my_widget');

Example Test #

Here's a complete example of how to use flutter_test_helpers in your tests:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_test_helpers/flutter_test_helpers.dart';

void main() {
  group('MyWidget Tests', () {
    testWidgets('should display and handle interactions', (WidgetTester tester) async {
      // Create test app with helpers
      final app = TestUtilities.createTestApp(
        WidgetTestingHelpers.createPaddedWidget(
          MyWidget(
            title: MockDataGenerators.randomString(10),
            color: MockDataGenerators.randomColor(),
          ),
        ),
      );

      await tester.pumpWidget(app);

      // Use helper methods to find and interact
      final titleFinder = TestUtilities.findByText('My Widget');
      expect(titleFinder, findsOneWidget);

      // Use extensions for easier interaction
      await tester.tapByKey(Key('action-button'));
      await tester.pumpAndSettle();

      // Wait for state changes
      await tester.waitForWidget(find.byType(SuccessWidget));
    });

    testWidgets('should pass visual regression test', (WidgetTester tester) async {
      final widget = MyWidget(
        title: 'Test Title',
        color: Colors.blue,
      );

      // Visual regression test
      await VisualRegressionTesting.expectWidgetMatchesGolden(
        tester,
        widget,
        goldenName: 'my_widget_golden',
      );
    });

    testWidgets('should meet performance requirements', (WidgetTester tester) async {
      final widget = MyWidget(
        title: 'Performance Test',
        color: Colors.red,
      );

      // Performance test
      final metrics = await PerformanceTesting.measureWidgetPerformance(tester, widget);
      expect(metrics.meetsRequirements, isTrue);
      expect(metrics.fps, greaterThan(30.0));
    });

    testWidgets('should capture screenshots', (WidgetTester tester) async {
      final widget = MyWidget(
        title: 'Screenshot Test',
        color: Colors.green,
      );

      // Screenshot test
      final file = await ScreenshotTesting.takeScreenshotAndSave(
        tester,
        widget,
        filename: 'my_widget_screenshot',
      );

      expect(file.existsSync(), isTrue);
    });
  });
}

Platform Support #

This package supports all Flutter platforms:

  • βœ… iOS - Full support
  • βœ… Android - Full support
  • βœ… Web - Full support
  • βœ… Windows - Full support
  • βœ… macOS - Full support
  • βœ… Linux - Full support
  • βœ… WASM - Compatible with Flutter WebAssembly

Requirements #

  • Flutter: >=3.10.0
  • Dart: >=3.0.0
  • Flutter Test: Included in Flutter SDK

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Author #

Dhia Bechattaoui

Support #

If you encounter any issues or have questions, please:

  1. Check the documentation
  2. Search existing issues
  3. Create a new issue

Made with ❀️ for the Flutter community

1
likes
90
points
162
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

Comprehensive Flutter testing toolkit with mock data generators, visual regression testing, performance testing, and screenshot testing utilities.

Repository (GitHub)
View/report issues

Topics

#testing #mock-data #test-utilities #widget-testing #flutter

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_test_helpers