Skip to content

Latest commit

 

History

History
149 lines (121 loc) · 3.86 KB

integration-testing.md

File metadata and controls

149 lines (121 loc) · 3.86 KB

Intro

To test how individual pieces work together as a whole, or capture the performance of an application running on a real device, use integration tests.

Setup

Create an app for testing:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Counter App',
      home: MyHomePage(title: 'Counter App Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              // Provide a Key to this specific Text widget. This allows
              // identifying the widget from inside the test suite,
              // and reading the text.
              key: const Key('counter'),
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // Provide a Key to this button. This allows finding this
        // specific button inside the test suite, and tapping it.
        key: const Key('increment'),
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Add the integration_test dependency to the app’s pubspec.yaml file:

dev_dependencies:
  integration_test:
    sdk: flutter
  flutter_test:
    sdk: flutter

Create and write the test files with 3 main steps:

  1. Initialize IntegrationTestWidgetsFlutterBinding, a singleton service that executes tests on a physical device.
  2. Interact and tests widgets using the WidgetTester class.
  3. Test the important scenarios.
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:introduction/main.dart';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  group('end-to-end test', () {
    testWidgets('tap on the floating action button, verify counter',
        (tester) async {
      // Load app widget.
      await tester.pumpWidget(const MyApp());

      // Verify the counter starts at 0.
      expect(find.text('0'), findsOneWidget);

      // Finds the floating action button to tap on.
      final Finder fab = find.byTooltip('Increment');

      // Emulate a tap on the floating action button.
      await tester.tap(fab);

      // Trigger a frame.
      await tester.pumpAndSettle();

      // Verify the counter increments by 1.
      expect(find.text('1'), findsOneWidget);
    });
  });
}

Run tests:

  1. Mobile:
  • Run a test file: flutter test integration_test/app_test.dart
  • Run all tests: flutter test integration_test
  1. Web:
  • Create a new directory named test_driver containing a new file named integration_test.dart:
    import 'package:integration_test/integration_test_driver.dart';
    
    Future<void> main() => integrationDriver();
  • Launch chromedriver as follows: chromedriver --port=4444
  • Run the following command:
    $ flutter drive \
    --driver=test_driver/integration_test.dart \
    --target=integration_test/app_test.dart \
    -d chrome // or `-d web-server` for a headless testing experience