Principes des tests de widgets
Apprenez à rédiger des tests de widgets pour vérifier isolément l’interface et le comportement de chaque widget, et garantir leur exactitude visuelle.
Principes des tests de widgets est une leçon Flutter Mobile Development gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Flutter Mobile Development, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Flutter Mobile Development comprend 4 leçons au total.
Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.
What is Widget Testing?
Welcome to widget testing! It's a key part of building robust Flutter apps.
Widget tests let you check if your individual UI components (widgets) look and behave as expected. Think of it as putting each piece of your app under a microscope.
- Focus: Individual widgets.
- Goal: Verify UI rendering and interaction in isolation.
Diving into `flutter_test`
Flutter provides a special package called flutter_test for writing widget tests. It's automatically included in new Flutter projects.
The core of widget testing is the testWidgets function. It gives you a WidgetTester to interact with your widgets and an environment to run them.
Where Do Tests Go?
Flutter test files typically live in the test/ folder of your project. For example, if you have a widget in lib/my_widget.dart, its test might be in test/my_widget_test.dart.
Each test file starts with importing package:flutter_test/flutter_test.dart and defines one or more testWidgets blocks.
Your Testing Helper: `WidgetTester`
The WidgetTester is your main tool for interacting with widgets during a test. It provides methods to:
pumpWidget(): Renders a widget tree.find: Locates widgets in the tree.tap(): Simulates a tap on a widget.pump(): Rebuilds the widget tree, often after an interaction.
It helps simulate how a user would interact with your app.
Testing a Basic Stateless Widget
Let's test a simple StatelessWidget. Imagine a widget that just shows some text.
We'll use tester.pumpWidget() to display our widget, then tester.find to locate the text, and finally expect() to assert that it's there.
import 'package:flutter/material.dart';
class MyTextWidget extends StatelessWidget {
final String message;
const MyTextWidget({Key? key, required this.message}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Test')),
body: Center(
child: Text(message),
),
),
);
}
}
void main() {
runApp(const MyTextWidget(message: "Hello CoddyKit!"));
}Code: Testing `MyTextWidget`
Here's how you'd write a test for our MyTextWidget. Notice how we wrap it in MaterialApp and Scaffold to give it a proper context for rendering.
We use find.text() to locate the text and expect() with findsOneWidget to confirm its presence.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// Assume MyTextWidget is defined in a separate file or above for testing
class MyTextWidget extends StatelessWidget {
final String message;
const MyTextWidget({Key? key, required this.message}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Test')),
body: Center(
child: Text(message),
),
),
);
}
}
void main() {
testWidgets('MyTextWidget displays correct message', (WidgetTester tester) async {
// Build our widget and trigger a frame.
await tester.pumpWidget(const MyTextWidget(message: 'Hello CoddyKit!'));
// Verify that our message appears.
expect(find.text('Hello CoddyKit!'), findsOneWidget);
expect(find.text('Goodbye!'), findsNothing);
});
}Interacting with Widgets
Widget tests can simulate user interactions. This is crucial for testing StatefulWidgets or widgets with buttons, text fields, etc.
tester.tap(finder): Simulates a tap on the widget found byfinder.tester.enterText(finder, text): Enters text into aTextField.tester.pump(): After an interaction that causes state changes (like a button tap), you must callpump()to rebuild the UI and reflect those changes.
Testing a Basic Stateful Widget
Let's create a simple counter widget. It has a text displaying a number and a button to increment it. We'll test its initial state and then its behavior after a tap.
import 'package:flutter/material.dart';
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
key: const Key('counterText'), // Added key for easy finding
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
key: const Key('incrementButton'), // Added key
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
),
);
}
}
void main() {
runApp(const CounterWidget());
}Code: Testing `CounterWidget`
Here's the test for our CounterWidget. We first verify the initial count, then simulate a tap on the increment button using its Key, and finally assert that the count has updated.
Remember to call tester.pump() after tester.tap() to rebuild the UI and see the state change.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// Assume CounterWidget is defined in a separate file or above for testing
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() { _counter++; });
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text('$_counter', key: const Key('counterText'), style: Theme.of(context).textTheme.headlineMedium),
],
),
),
floatingActionButton: FloatingActionButton(
key: const Key('incrementButton'),
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
),
);
}
}
void main() {
testWidgets('CounterWidget increments counter on button tap', (WidgetTester tester) async {
// Build our CounterWidget.
await tester.pumpWidget(const CounterWidget());
// Verify that the counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the 'increment' icon and trigger a frame.
await tester.tap(find.byKey(const Key('incrementButton')));
await tester.pump(); // Rebuild the widget after interaction
// Verify that the counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}Essential Test Matchers
When writing tests, you'll use expect() with various "matchers" to verify conditions. Here are some common ones:
findsOneWidget: Expects exactly one widget matching the finder.findsNWidgets(N): Expects exactly N widgets.findsNothing: Expects no widgets matching the finder.findsWidgets: Expects one or more widgets.
These help you precisely assert what should or shouldn't be on screen.
Quick Check on Testing
Imagine you have a Text('Hello World') widget. Which find method would you use to confirm this text is visible on the screen after calling tester.pumpWidget()?
Recap: Widget Testing Basics
Great job! You've learned the fundamentals of widget testing:
- Widget tests verify individual UI components.
- The
flutter_testpackage provides tools liketestWidgetsandWidgetTester. - You use
tester.pumpWidget()to render,findto locate, andexpect()with matchers to assert. tester.tap()andtester.pump()simulate user interaction and update the UI.
Next, you'll explore more advanced testing techniques!
Questions Fréquemment Posées
La leçon « Principes des tests de widgets » est-elle gratuite ?
Oui — le texte complet de « Principes des tests de widgets » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Flutter Mobile Development, passe à CoddyKit PRO. Le cours Flutter Mobile Development comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Principes des tests de widgets » ?
Apprenez à rédiger des tests de widgets pour vérifier isolément l’interface et le comportement de chaque widget, et garantir leur exactitude visuelle. Tu pratiques Flutter Mobile Development avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Flutter Mobile Development ?
Aucune expérience préalable n'est requise. Flutter Mobile Development sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Principes des tests de widgets » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Flutter Mobile Development ?
Oui. Chaque leçon Flutter Mobile Development inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Principes des tests de widgets
- Tests d’intégration
- Outils et techniques de débogage
- Tests unitaires et simulations