Tester une application Flutter

Flutter est un kit d'interface utilisateur Google qui permet de développer des applications esthétiques compilées de manière native pour les mobiles, le Web et les ordinateurs de bureau, à partir d'un seul codebase.

Dans cet atelier de programmation, vous allez développer et tester une application Flutter simple qui utilisera le package Provider pour gérer l'état.

Ce que vous allez apprendre

  • Créer des tests de widgets en utilisant le framework de tests de widgets
  • Créer un test d'intégration pour évaluer l'interface utilisateur et les performances de l'application à l'aide du package integration_test
  • Tester des classes de données (fournisseurs) à l'aide de tests unitaires

Ce que vous allez faire

Dans cet atelier de programmation, vous allez commencer par développer une application simple contenant une liste d'éléments. Pour que vous puissiez passer directement aux tests, nous vous fournissons le code source. Cette application permet d'effectuer les opérations suivantes :

  • Ajouter les éléments aux favoris
  • Afficher la liste des favoris
  • Supprimer des éléments de la liste des favoris

Une fois l'application terminée, vous allez écrire les tests suivants :

  • Tests unitaires pour valider les opérations d'ajout et de suppression
  • Tests des widgets des pages d'accueil et de favoris
  • Tests de l'interface utilisateur et des performances de l'application entière à l'aide des tests d'intégration

GIF illustrant l'application exécutée sous Android

Qu'attendez-vous de cet atelier de programmation ?

Je suis novice en la matière et je voudrais avoir un bon aperçu. Je connais un peu le sujet, mais j'aimerais revoir certains points. Je recherche un exemple de code à utiliser dans mon projet. Je cherche des explications sur un point spécifique.

Pour cet atelier, vous avez besoin de deux logiciels : le SDK Flutter et un éditeur.

Vous pouvez exécuter cet atelier de programmation sur l'un des appareils suivants :

  • Un appareil physique (Android ou iOS) connecté à votre ordinateur et réglé en mode développeur
  • Le simulateur iOS (outils Xcode à installer)
  • L'émulateur Android (qui doit être configuré dans Android Studio)

Créer une application Flutter et modifier les dépendances

Cet atelier de programmation consiste à tester une application mobile Flutter. Vous allez commencer par la créer rapidement à l'aide des fichiers sources que vous aurez copiés et collés. Le reste de l'atelier porte sur l'apprentissage des différents types de tests.

b2f84ff91b0e1396.pngCréez une application Flutter simple à partir d'un modèle en suivant les instructions de la section Premiers pas avec votre première application Flutter. Nommez le projet testing_app (au lieu de myapp). Vous allez modifier cette application de départ pour créer l'application finale.

b2f84ff91b0e1396.pngDans votre IDE ou éditeur, ouvrez le fichier pubspec.yaml. Ajoutez les dépendances suivantes marquées comme new, puis enregistrez le fichier. (Vous pouvez supprimer les commentaires pour que le fichier soit plus lisible.)

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.3
  provider: ^4.1.3            # new

dev_dependencies:
  flutter_test:
    sdk: flutter
  integration_test: ^1.0.1    # new
  test: ^1.14.4               # new
  1. Cliquez sur le bouton Pub get de votre IDE ou, dans la ligne de commande, exécutez flutter pub get à la racine du projet.

Si une erreur s'affiche, vérifiez que les retraits dans le bloc dependencies sont parfaitement identiques à ceux ci-dessus (avec des espaces et non des tabulations). Les fichiers YAML tiennent compte des espaces blancs.

Vous allez maintenant créer l'application pour pouvoir la tester. Elle contient les fichiers suivants :

  • lib/main.dart (fichier principal dans lequel l'application démarre)
  • lib/screens/home.dart (crée une liste d'éléments)
  • lib/screens/favorites.dart (crée la disposition de la liste des favoris)
  • lib/models/favorites.dart (crée la classe de modèle pour la liste des favoris)

Remplacer le contenu du fichier lib/main.dart

b2f84ff91b0e1396.pngRemplacez le contenu du fichier lib/main.dart par le code suivant :

lib/main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/favorites.dart';
import 'package:testing_app/screens/home.dart';

void main() {
  runApp(TestingApp());
}

class TestingApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Favorites>(
      create: (context) => Favorites(),
      child: MaterialApp(
        title: 'Testing Sample',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        routes: {
          HomePage.routeName: (context) => HomePage(),
          FavoritesPage.routeName: (context) => FavoritesPage(),
        },
        initialRoute: HomePage.routeName,
      ),
    );
  }
}

Ajouter la page d'accueil dans le fichier lib/screens/home.dart

b2f84ff91b0e1396.pngDans le répertoire lib, créez d'abord un sous-répertoire screens, puis dans celui-ci, un fichier nommé home.dart. Dans lib/screens/home.dart, ajoutez le code suivant :

lib/screens/home.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/favorites.dart';

class HomePage extends StatelessWidget {
  static String routeName = '/';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Testing Sample'),
        actions: <Widget>[
          TextButton.icon(
            style: TextButton.styleFrom(primary: Colors.white),
            onPressed: () {
              Navigator.pushNamed(context, FavoritesPage.routeName);
            },
            icon: Icon(Icons.favorite_border),
            label: Text('Favorites'),
          ),
        ],
      ),
      body: ListView.builder(
        itemCount: 100,
        cacheExtent: 20.0,
        padding: const EdgeInsets.symmetric(vertical: 16),
        itemBuilder: (context, index) => ItemTile(index),
      ),
    );
  }
}

class ItemTile extends StatelessWidget {
  final int itemNo;

  const ItemTile(
    this.itemNo,
  );

  @override
  Widget build(BuildContext context) {
    var favoritesList = Provider.of<Favorites>(context);

    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Colors.primaries[itemNo % Colors.primaries.length],
        ),
        title: Text(
          'Item $itemNo',
          key: Key('text_$itemNo'),
        ),
        trailing: IconButton(
          key: Key('icon_$itemNo'),
          icon: favoritesList.items.contains(itemNo)
              ? Icon(Icons.favorite)
              : Icon(Icons.favorite_border),
          onPressed: () {
            !favoritesList.items.contains(itemNo)
                ? favoritesList.add(itemNo)
                : favoritesList.remove(itemNo);
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text(favoritesList.items.contains(itemNo)
                    ? 'Added to favorites.'
                    : 'Removed from favorites.'),
                duration: Duration(seconds: 1),
              ),
            );
          },
        ),
      ),
    );
  }
}

Ajouter la page des favoris dans le fichier lib/screens/favorites.dart

b2f84ff91b0e1396.pngDans le répertoire lib/screens, créez un fichier nommé favorites.dart dans lequel vous ajouterez ensuite le code suivant :

lib/screens/favorites.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';

class FavoritesPage extends StatelessWidget {
  static String routeName = '/favorites_page';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Favorites'),
      ),
      body: Consumer<Favorites>(
        builder: (context, value, child) => ListView.builder(
          itemCount: value.items.length,
          padding: const EdgeInsets.symmetric(vertical: 16),
          itemBuilder: (context, index) => FavoriteItemTile(value.items[index]),
        ),
      ),
    );
  }
}

class FavoriteItemTile extends StatelessWidget {
  final int itemNo;

  const FavoriteItemTile(
    this.itemNo,
  );

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Colors.primaries[itemNo % Colors.primaries.length],
        ),
        title: Text(
          'Item $itemNo',
          key: Key('favorites_text_$itemNo'),
        ),
        trailing: IconButton(
          key: Key('remove_icon_$itemNo'),
          icon: Icon(Icons.close),
          onPressed: () {
            Provider.of<Favorites>(context, listen: false).remove(itemNo);
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('Removed from favorites.'),
                duration: Duration(seconds: 1),
              ),
            );
          },
        ),
      ),
    );
  }
}

Créer le modèle Favorites dans le fichier lib/models/favorites.dart

b2f84ff91b0e1396.pngCréez d'abord un répertoire models, puis dans celui-ci, un fichier nommé favorites.dart dans lequel vous ajouterez le code suivant :

lib/models/favorites.dart

import 'package:flutter/material.dart';

/// The [Favorites] class holds a list of favorite items saved by the user.
class Favorites extends ChangeNotifier {
  final List<int> _favoriteItems = [];

  List<int> get items => _favoriteItems;

  void add(int itemNo) {
    _favoriteItems.add(itemNo);
    notifyListeners();
  }

  void remove(int itemNo) {
    _favoriteItems.remove(itemNo);
    notifyListeners();
  }
}

L'application est maintenant terminée, mais n'a pas encore été testée.

b2f84ff91b0e1396.pngExécutez l'application en cliquant sur l'icône Exécuter 6869d41b089cc745.png dans l'éditeur. Lorsque vous exécutez une application pour la première fois, l'opération peut prendre un certain temps. L'application est plus rapide aux étapes suivantes. Elle devrait se présenter comme suit :

be938199b599b605.png

L'application affiche une liste d'éléments. Pour ajouter un élément à vos favoris, appuyez sur l'icône correspondante en forme de cœur (de sorte que ce cœur soit rempli). Le bouton Favoris de la AppBar vous redirige vers un second écran qui contient la liste des favoris.

L'application est maintenant prête à être testée (ce que vous allez faire à l'étape suivante).

Vous commencerez par des tests unitaires du modèle favorites. Qu'est-ce qu'un test unitaire ? Un test unitaire permet de vérifier que chaque unité individuelle de logiciel (souvent une fonction) exécute correctement la tâche prévue.

Tous les fichiers de test d'une application Flutter (hormis pour les tests d'intégration) sont placés dans le répertoire test.

Supprimer test/widget_test.dart

b2f84ff91b0e1396.pngAvant de commencer les tests, supprimez le fichier widget_test.dart. Vous allez ajouter vos propres fichiers de test.

Créer un fichier de test

Tout d'abord, vous allez tester la méthode add() dans le modèle Favorites pour vérifier qu'un nouvel élément est ajouté à la liste, et que celle-ci reflète bien cette modification. Par convention, la structure de répertoires dans le répertoire test reprend celle du répertoire lib. Les fichiers Dart portent le même nom, mais avec la mention _test en plus.

b2f84ff91b0e1396.pngDans le répertoire test, créez d'abord un sous-répertoire models, puis dans celui-ci, un fichier favourites_test.dart contenant ce qui suit :

test/models/favorites_test.dart

import 'package:test/test.dart';
import 'package:testing_app/models/favorites.dart';

void main() {
  group('App Provider Tests', () {
    var favorites = Favorites();

    test('A new item should be added', () {
      var number = 35;
      favorites.add(number);
      expect(favorites.items.contains(number), true);
    });
  });
}

Le framework de test Flutter vous permet d'associer des tests similaires liés les uns aux autres dans un groupe. Il peut y avoir plusieurs groupes dans un seul fichier de test destinés à tester différentes parties du fichier correspondant dans le répertoire /lib.

La méthode test() utilise deux paramètres de position : la description du test et le callback dans lequel vous écrivez en fait le test.

b2f84ff91b0e1396.pngTestez la suppression d'un élément de la liste. Copiez et collez le test suivant dans le même groupe de test. Ajoutez le code suivant au fichier de test :

test/models/favorites_test.dart

test('An item should be removed', () {
  var number = 45;
  favorites.add(number);
  expect(favorites.items.contains(number), true);
  favorites.remove(number);
  expect(favorites.items.contains(number), false);
});

Exécuter le test

b2f84ff91b0e1396.pngSi votre application s'exécute dans votre émulateur ou appareil, fermez-la avant de continuer.

b2f84ff91b0e1396.pngDans la ligne de commande, accédez au répertoire racine du projet et saisissez la commande suivante :

$ flutter test test/models/favorites_test.dart

Si tout fonctionne correctement, vous devriez voir un message de ce type :

00:06 +2: All tests passed!

Fichier de test complet : test/models/favorites_test.dart.

Pour en savoir plus sur les tests unitaires, lisez l'introduction aux tests unitaires.

Au cours de cette étape, vous allez tester des widgets. Les tests de widgets sont propres à Flutter. Vous pouvez tester ici chaque widget de votre choix. Cette étape permet de tester les écrans (HomePage et FavoritesPage) individuellement.

Les tests de widgets font appel à la fonction testWidget() au lieu de la fonction test(). Ils utilisent également deux paramètres : la description, et le callback. Ici, le rappel utilise un WidgetTester comme argument.

Les tests de widgets utilisent TestFlutterWidgetsBinding, une classe qui fournit les mêmes ressources à vos widgets que dans une application en cours d'exécution (par exemple, des informations sur la taille de l'écran, la possibilité de planifier des animations, etc.), mais sans l'application réelle. Au lieu de cela, un environnement virtuel est utilisé pour exécuter le widget, le mesurer, etc., puis tester les résultats. Ici, pumpWidget lance le processus en demandant au framework d'installer et de mesurer un widget particulier comme il le ferait dans une application complète.

Le framework de test de widgets fournit des outils de recherche pour trouver les widgets (par exemple, text(), byType(), byIcon()) et des outils de mise en correspondance pour vérifier les résultats.

Commencez par tester le widget HomePage.

Créer un fichier de test

Le premier test consiste à vérifier si la HomePage défile correctement.

b2f84ff91b0e1396.pngDans le répertoire test, créez un fichier que vous nommerez home_test.dart et dans lequel vous ajouterez le code suivant :

test/home_test.dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/home.dart';

Widget createHomeScreen() => ChangeNotifierProvider<Favorites>(
      create: (context) => Favorites(),
      child: MaterialApp(
        home: HomePage(),
      ),
    );

void main() {
  group('Home Page Widget Tests', () {
    testWidgets('Testing Scrolling', (tester) async {
      await tester.pumpWidget(createHomeScreen());
      expect(find.text('Item 0'), findsOneWidget);
      await tester.fling(find.byType(ListView), Offset(0, -200), 3000);
      await tester.pumpAndSettle();
      expect(find.text('Item 0'), findsNothing);
    });
  });
}

La fonction createHomeScreen() permet de créer une application qui charge le widget à tester dans un MaterialApp, encapsulé dans un ChangeNotifierProvider. Dans l'arborescence des widgets, le widget HomePage doit toujours figurer au-dessous de ces deux widgets pour hériter de ceux-ci et accéder aux données qu'ils proposent. Cette fonction est transmise en tant que paramètre à la fonction pumpWidget().

Vérifiez ensuite si le framework peut trouver une ListView affichée à l'écran.

b2f84ff91b0e1396.pngAjoutez l'extrait de code suivant à home_test.dart :

test/home_test.dart

group('Home Page Widget Tests', () {

  // BEGINNING OF NEW CONTENT
  testWidgets('Testing if ListView shows up', (tester) async {
    await tester.pumpWidget(createHomeScreen());
    expect(find.byType(ListView), findsOneWidget);
  });
  // END OF NEW CONTENT

  testWidgets('Testing Scrolling', (tester) async {
    await tester.pumpWidget(createHomeScreen());
    expect(find.text('Item 0'), findsOneWidget);
    await tester.fling(find.byType(ListView), Offset(0, -200), 3000);
    await tester.pumpAndSettle();
    expect(find.text('Item 0'), findsNothing);
  });
});

Exécuter le test

Vous pouvez exécuter des tests de widgets de la même manière que des tests unitaires, mais l'utilisation d'un appareil ou d'un émulateur vous permet de regarder le test en cours et également de redémarrer l'application à chaud.

b2f84ff91b0e1396.pngBranchez votre appareil ou démarrez l'émulateur.

b2f84ff91b0e1396.pngÀ partir de la ligne de commande, accédez au répertoire racine du projet et saisissez la commande suivante :

$ flutter run test/home_test.dart

Si tout fonctionne, vous devriez obtenir un résultat semblable à celui-ci :

Launching test/home_test.dart on Mi A3 in debug mode...
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done                        62.7s
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...                 5.8s
Waiting for Mi A3 to report its views...                            16ms
I/flutter ( 1616): 00:00 +0: Home Page Widget Tests Testing if ListView shows up
Syncing files to device Mi A3...
I/flutter ( 1616): 00:02 +1: Home Page Widget Tests Testing Scrolling
Syncing files to device Mi A3...                                                 4,008ms (!)

Flutter run key commands.
r Hot reload. 🔥🔥🔥
R Hot restart.
h Repeat this help message.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
An Observatory debugger and profiler on Mi A3 is available at:
http://127.0.0.1:40433/KOsGesHSxR8=/
I/flutter ( 1616): 00:00 +0: Home Page Widget Tests Testing if ListView shows up
I/flutter ( 1616): 00:02 +1: Home Page Widget Tests Testing Scrolling
I/flutter ( 1616): 00:09 +3: All tests passed!

Vous allez ensuite modifier le fichier de test et appuyer sur Shift + R pour redémarrer l'application et exécuter à nouveau tous les tests.

b2f84ff91b0e1396.pngAjoutez d'autres tests au groupe qui teste les widgets Homepage. Copiez le test suivant dans votre fichier :

test/home_test.dart

testWidgets('Testing IconButtons', (tester) async {
  await tester.pumpWidget(createHomeScreen());
  expect(find.byIcon(Icons.favorite), findsNothing);
  await tester.tap(find.byIcon(Icons.favorite_border).first);
  await tester.pumpAndSettle(Duration(seconds: 1));
  expect(find.text('Added to favorites.'), findsOneWidget);
  expect(find.byIcon(Icons.favorite), findsWidgets);
  await tester.tap(find.byIcon(Icons.favorite).first);
  await tester.pumpAndSettle(Duration(seconds: 1));
  expect(find.text('Removed from favorites.'), findsOneWidget);
  expect(find.byIcon(Icons.favorite), findsNothing);
});

Ce test permet de vérifier que lorsque l'utilisateur appuie sur l'IconButton, le cœur vide (Icons.favorite_border) devient plein (Icons.favorite), puis redevient vide (Icons.favorite_border) si l'utilisateur appuie de nouveau dessus.

b2f84ff91b0e1396.pngAppuyez sur Shift + R. L'application redémarre à chaud et tous les tests sont à nouveau exécutés.

Fichier de test complet : test/home_test.dart.

b2f84ff91b0e1396.pngSuivez la même procédure pour tester la FavoritesPage avec le code suivant, puis exécutez le test.

test/favorites_test.dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/favorites.dart';

Favorites favoritesList;

Widget createFavoritesScreen() => ChangeNotifierProvider<Favorites>(
      create: (context) {
        favoritesList = Favorites();
        return favoritesList;
      },
      child: MaterialApp(
        home: FavoritesPage(),
      ),
    );

void addItems() {
  for (var i = 0; i < 10; i += 2) {
    favoritesList.add(i);
  }
}

void main() {
  group('Favorites Page Widget Tests', () {
    testWidgets('Test if ListView shows up', (tester) async {
      await tester.pumpWidget(createFavoritesScreen());
      addItems();
      await tester.pumpAndSettle();
      expect(find.byType(ListView), findsOneWidget);
    });

    testWidgets('Testing Remove Button', (tester) async {
      await tester.pumpWidget(createFavoritesScreen());
      addItems();
      await tester.pumpAndSettle();
      var totalItems = tester.widgetList(find.byIcon(Icons.close)).length;
      await tester.tap(find.byIcon(Icons.close).first);
      await tester.pumpAndSettle();
      expect(tester.widgetList(find.byIcon(Icons.close)).length,
          lessThan(totalItems));
      expect(find.text('Removed from favorites.'), findsOneWidget);
    });
  });
}

Ce test permet de vérifier si un élément disparaît lorsqu'un utilisateur appuie sur le bouton de fermeture (supprimer).

Pour en savoir plus sur les tests de widgets, consultez les ressources ci-dessous :

Les tests d'intégration permettent de tester la façon dont des éléments individuels d'une application fonctionnent ensemble globalement. Le package integration_test est utilisé pour effectuer des tests d'intégration dans Flutter. Il s'agit de la version Flutter de Selenium WebDriver (Web générique), Protractor (Angular), Espresso (Android) ou Earl Grey (iOS). Le package utilise flutter_driver en interne pour effectuer le test sur un appareil.

Instrumenter l'application

Pour écrire un test d'intégration, vous devez d'abord instrumenter l'application. Instrumenter une application signifie la configurer de sorte que le pilote puisse accéder à son IUG et à ses fonctions pour créer et exécuter un test automatisé. Les tests d'intégration sont placés dans un répertoire nommé integration_test. Au cours de cette étape, vous allez ajouter les fichiers suivants pour effectuer des tests d'intégration :

  • integration_test/driver.dart : instrumente l'application
  • integration_test/app_test.dart : exécute les tests réels sur l'application

b2f84ff91b0e1396.pngDans le répertoire racine du projet, créez d'abord un sous-répertoire nommé integration_test, puis dans celui-ci, un fichier driver.dart dans lequel vous ajouterez le code suivant :

integration_test/driver.dart

import 'package:integration_test/integration_test_driver.dart';

Future<void> main() => integrationDriver();

Ce code active le pilote de test d'intégration, puis attend l'exécution du test. Les données de réponse sont stockées dans un fichier nommé integration_response_data.json après l'exécution des tests.

Écrire le test

b2f84ff91b0e1396.pngCréez un fichier et nommez-le app_test.dart.

integration_test/app_test.dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:testing_app/main.dart';

void main() {
  group('Testing App Performance Tests', () {
    final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
        as IntegrationTestWidgetsFlutterBinding;

    binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
  });
}

La fonction ensureInitialized() vérifie si le pilote de test d'intégration est initialisé ou non, et le réinitialise si nécessaire. La framePolicy, lorsqu'elle est définie sur fullyLive à partir de l'énumération LiveTestWidgetsFlitterBindingFramePolicy, est la mieux adaptée pour tester des situations avec beaucoup d'animations.

Ensuite, testez les performances de défilement de l'application et enregistrez-les à l'aide de la fonction watchPerformance().

b2f84ff91b0e1396.pngCopiez le code suivant dans le groupe de test que vous venez de créer :

integration_test/app_test.dart

testWidgets('Scrolling test', (tester) async {
  await tester.pumpWidget(TestingApp());

  final listFinder = find.byType(ListView);

  await binding.watchPerformance(() async {
    await tester.fling(listFinder, Offset(0, -500), 10000);
    await tester.pumpAndSettle();

    await tester.fling(listFinder, Offset(0, 500), 10000);
    await tester.pumpAndSettle();
  }, reportKey: 'scrolling_summary');
});

Ce test fait d'abord défiler la liste des éléments très rapidement, puis toute la page vers le haut. La fonction watchPerformance() enregistre les actions et génère un résumé de la chronologie, qui est ensuite renvoyé sous forme de données de réponse au pilote de test dans le fichier driver.dart.

Testez ensuite les opérations add et remove.

b2f84ff91b0e1396.pngCollez le test suivant dans le même groupe :

integration_test/app_test.dart

testWidgets('Favorites operations test', (tester) async {
  await tester.pumpWidget(TestingApp());

  final iconKeys = [
    'icon_0',
    'icon_1',
    'icon_2',
  ];

  for (var icon in iconKeys) {
    await tester.tap(find.byKey(ValueKey(icon)));
    await tester.pumpAndSettle(Duration(seconds: 1));

    expect(find.text('Added to favorites.'), findsOneWidget);
  }

  await tester.tap(find.text('Favorites'));
  await tester.pumpAndSettle();

  final removeIconKeys = [
    'remove_icon_0',
    'remove_icon_1',
    'remove_icon_2',
  ];

  for (final iconKey in removeIconKeys) {
    await tester.tap(find.byKey(ValueKey(iconKey)));
    await tester.pumpAndSettle(Duration(seconds: 1));

    expect(find.text('Removed from favorites.'), findsOneWidget);
  }
});

Exécuter le test

b2f84ff91b0e1396.pngBranchez votre appareil ou démarrez l'émulateur.

b2f84ff91b0e1396.pngDans la ligne de commande, accédez au répertoire racine du projet et saisissez la commande suivante :

$ flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart --profile

Si tout fonctionne, vous devriez obtenir un résultat semblable à celui-ci :

Running "flutter pub get" in step_07...                            930ms
Running Gradle task 'assembleProfile'...
Running Gradle task 'assembleProfile'... Done                      31.3s
✓ Built build/app/outputs/flutter-apk/app-profile.apk (11.3MB).
Installing build/app/outputs/flutter-apk/app.apk...                277ms
VMServiceFlutterDriver: Connecting to Flutter application at http://127.0.0.1:62862/K6QKjUNab8c=/
VMServiceFlutterDriver: Isolate found with number: 1935648057883071
VMServiceFlutterDriver: Isolate is paused at start.
VMServiceFlutterDriver: Attempting to resume isolate
I/flutter (24385): 00:00 +0: Testing App Performance Tests Scrolling test
VMServiceFlutterDriver: Connected to Flutter application.
I/flutter (24385): 00:08 +1: Testing App Performance Tests Favorites operations
test
I/flutter (24385): 00:17 +2: Testing App Performance Tests (tearDownAll)
I/flutter (24385): 00:17 +3: All tests passed!
All tests passed.

Une fois le test réussi, un fichier nommé integration_response_data.json devrait figurer dans le répertoire build à la racine du projet. Ce fichier contient les données de réponse renvoyées par le test lors de son exécution (dans le cas présent, il s'agit du scrolling_summary). Ouvrez-le dans n'importe quel éditeur de texte pour le consulter. Avec une configuration plus avancée, vous pourriez enregistrer un récapitulatif à chaque exécution du test et créer un graphique des résultats.

Fichier de test complet : integration_test/app_test.dart.

Pour en savoir plus sur les tests (d'intégration) avec le pilote Flutter, consultez les ressources suivantes :

Vous avez terminé cet atelier de programmation et appris plusieurs manières de tester une application Flutter.

Ce que vous avez appris

  • Tester des widgets en utilisant le framework de test de widgets
  • Tester l'interface utilisateur de l'application via des tests d'intégration
  • Tester les performances d'une application via des tests d'intégration
  • Tester les fournisseurs via des tests unitaires

Pour en savoir plus sur les tests dans Flutter, consultez les pages suivantes :