Take screenshot during Flutter integration tests
Tags: flutter, dart, testing, tutorial
Published: 2021-10-24 22:40:52

I would like introduce you a simple manual about how take screenshot during integration tests in Flutter.

From Flutter 2.5.0 you can take screenshot in your integration tests by very simple way.

First if you didn't setup integration tests yet, setup it by this manual: https://flutter.dev/docs/cookbook/testing/integration/introduction

When you have already it, you can continue by this way:
<br />

#### 1) Replace your test_driver/integration_test.dart by this code:
```dart
import 'dart:io';
import 'package:integration_test/integration_test_driver_extended.dart';

Future<void> main() async {
  try {
    await integrationDriver(
      onScreenshot: (String screenshotName, List<int> screenshotBytes) async {
        final File image = await File('screenshots/$screenshotName.png').create(recursive: true);
        image.writeAsBytesSync(screenshotBytes);
        return true;
      },
    );
  } catch (e) {
    print('Error occured: $e');
  }
}
```
It add **onScreenshot** event handler into your integration tests and after take your screenshot it will save it into *screenshots* directory in your project. (This directory will be created when doesn't exists.)
<br />

#### 2) Go into your integration_test/app_test.dart and add:
```dart
final binding = IntegrationTestWidgetsFlutterBinding();
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
```
This must be before all your testWidgets when tests are initialized.
<br />

#### 3) Into your test add:
```dart
await binding.takeScreenshot('test-screenshot');
```
If you run your tests on Android device, you must also add `convertFlutterSurfaceToImage()` function before `takeScreenshot()` because there must be converted a Flutter surface into image:
```dart
await binding.convertFlutterSurfaceToImage();
await tester.pumpAndSettle();
await binding.takeScreenshot('test-screenshot');
```
For iOS or web you don't need this convert function.
<br />

#### 4) You can create a simple helper function for take screenshot in various devices:
```dart
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;

takeScreenshot(tester, binding) async {
  if (kIsWeb) {
    await binding.takeScreenshot('test-screenshot');
    return;
  } else if (Platform.isAndroid) {
    await binding.convertFlutterSurfaceToImage();
    await tester.pumpAndSettle();
  }
  await binding.takeScreenshot('test-screenshot');
}
```
<br />

So your tests can finally looks like this:
```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:example_integration_test_screenshot/main.dart';
import 'helper.dart';


void main() {
  group('Test App', () {
  final binding = IntegrationTestWidgetsFlutterBinding();
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

    testWidgets('Test with take screenshot', (tester) async {
      await tester.pumpWidget(MyApp());
      await tester.pumpAndSettle();

      await tester.tap(find.byIcon(Icons.add));
      await tester.tap(find.byIcon(Icons.add));
      await tester.tap(find.byIcon(Icons.add));
      await tester.pumpAndSettle();

      await takeScreenshot(tester, binding);
    });
  });
}
```

## Conclusion
So that is all. After run of your tests you can see a generated screenshot in `screenshots/test-screenshot.png` file:
![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijyqdd9r3tke05uo3tpa.png)

I hope that this article was useful and you can support me by ❤️ or some comments below. 🙂