Adaptive Test

logo

Devtools to write stunning widget test in Flutter.
Made by Theodo Apps ❤ī¸đŸ’™đŸ’›.

Example

Table of Contents

  1. Features
  2. Getting Started
  3. Usage
  4. Migration Guide
  5. Additional Information

Features

Use this package in your tests to:

  • Generate golden files for different devices during tests
  • Load fonts
  • Set window sizes and pixel density
  • Await image rendering
  • Render physical and system UI layers
  • Render a keyboard during tests
  • Set a preferred OS for running tests
  • Configure a difference tolerance threshold for file comparison

Getting Started

  1. Add adaptive_test to your dev dependencies.

  2. Create a flutter_test_config.dart file at the root of your test folder with a testExecutable function:

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  await testMain();
}

For more information, see the official Flutter documentation.

Usage

Rendering Custom Fonts

  1. Add your fonts to your app assets folders.
  2. Add your fonts to your Flutter assets in pubspec.yaml:
flutter:
  fonts:
  - family: Roboto
    fonts:
      - asset: fonts/Roboto-Black.ttf
  1. In your flutter_test_config.dart, call loadFonts():
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  TestWidgetsFlutterBinding.ensureInitialized();
  await loadFonts();
  await testMain();
}

ℹī¸ loadFonts() loads fonts from pubspec.yaml and from every separate package dependency as well.

Setting Up Test Devices

  1. Define a set of device variants:
final defaultDeviceConfigs = {
  iPhone16,
  pixel9,
};
  1. Use the AdaptiveTestConfiguration singleton to set variants:
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  TestWidgetsFlutterBinding.ensureInitialized();
  AdaptiveTestConfiguration.instance
    ..setDeviceVariants(defaultDeviceConfigs);
  await loadFonts();
  await testMain();
}

Configuring Difference Threshold

To allow for small pixel differences between processors, add setupFileComparatorWithThreshold() to your flutter_test_config.dart:

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  TestWidgetsFlutterBinding.ensureInitialized();
  AdaptiveTestConfiguration.instance
    ..setDeviceVariants(defaultDeviceConfigs);
  await loadFonts();
  setupFileComparatorWithThreshold();
  await testMain();
}

Enforcing Test Platform

Configure AdaptiveTestConfiguration to enforce a specific test platform:

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  TestWidgetsFlutterBinding.ensureInitialized();
  AdaptiveTestConfiguration.instance
    ..setEnforcedTestPlatform(TargetPlatform.macOS)
    ..setDeviceVariants(defaultDeviceConfigs);
  await loadFonts();
  setupFileComparatorWithThreshold();
  await testMain();
}

To skip tests instead of throwing an error on unintended platforms:

AdaptiveTestConfiguration.instance
  ..setEnforcedTestPlatform(TargetPlatform.macOS)
  ..setFailTestOnWrongPlatform(false)
  ..setDeviceVariants(defaultDeviceConfigs);

Writing a Test

Use the testAdaptiveWidgets function:

void main() {
  testAdaptiveWidgets(
    'Test description',
    (tester, variant) async {
      await tester.pumpWidget(
        AdaptiveWrapper(
          windowConfig: variant,
          tester: tester,
          child: const App(),
        ),
      );

      await tester.expectGolden<App>(variant);
    },
  );
}

Migration Guide

Migrating to version 0.7.x Version 0.7.0 introduces several breaking changes and new features:
  1. Breaking Change: loadFonts() no longer accepts a packages argument. loadFontsFromPackage() was removed.

    • Update your flutter_test_config.dart:
      // Old
      await loadFonts('my_package');
      // or
      await loadFontsFromPackage(
        package: Package(
          name: 'my_package',
          relativePath: '../package',
        ),
      );
      
      // New
      await loadFonts();
      
    • loadFonts() now supports custom icon fonts like material_symbols_icons.
  2. Breaking Change: WindowConfigData now includes a keyboardName property.

    • Update your custom device configurations to include this new property.
Migrating to version 0.5.x

Version 0.5.0 introduces a new default file name for goldens that's compatible with Windows file systems. To rename your existing golden files, use the following script:

#!/bin/bash

rename_files_in_preview() {
    find . -type d -name "preview" | while read -r dir; do
        echo "Processing directory: $dir"
        find "$dir" -type f | while read -r file; do
            new_name=$(echo "$file" | sed 's/:/-/g')
            if [ "$file" != "$new_name" ]; then
                mv "$file" "$new_name"
                echo "Renamed $file to $new_name"
            fi
        done
    done
}

rename_files_in_preview

Save this script as a .sh file and run it from your project root directory.

Additional Information

We welcome feedback, issues, contributions, and suggestions! Feel free to contribute to the development of this package.

👉 About Theodo Apps

We are a 130 people company developing and designing universal applications with React Native and Flutter using the Lean & Agile methodology. To get more information on the solutions that would suit your needs, feel free to get in touch by email or through or contact form!

We will always answer you with pleasure 😁

Libraries

adaptive_test