I have a saying that I use in my daily life: "Let me take care of future Luke". I usually say this when I wash my bedsheets, but I feel too lazy to immediately put on new ones. "Taking care of future Luke" in this instance would be to change them there and then, as opposed to remembering I need to do so as I'm about to roll into bed!
I do plan on building real apps using Flutter, so of course, I needed to learn how to do this the Flutter way! In the event of a major upgrade, those tests would give me the confidence to upgrade safely, i.e., I'm taking care of future Luke.
Unit testing
Unit testing is a type of testing that focuses on testing individual units of code, such as functions, classes, and modules. Unit tests are typically written in isolation from the rest of the application, and they should be fast and easy to run.
The following code example shows a simple unit test for a function that takes a string and returns the number of words in the string:
import 'package:test/test.dart';
int countWords(String string) {
return string.split(' ').length;
}
void main() {
test('countWords() returns the correct number of words', () {
expect(countWords('Hello, world!'), equals(2));
});
}
To run the test, simply type
flutter test
in the terminal.In my "Networking With Flutter" and "Hex Codes In Flutter" tutorials, I provide more real-world examples of unit tests.
Widget testing
Widget testing is a type of testing that focuses on testing widgets. Widget tests are typically written to verify that widgets behave as expected when they are interacted with by the user.
The following code example shows a simple widget test for a button widget:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Button widget', () {
testWidgets('Button can be clicked', (tester) async {
final completer = Completer<void>();
Widget widget = Directionality(
textDirection: TextDirection.ltr,
child: TextButton(
onPressed: completer.complete,
child: const Text('Tap me!'),
),
);
// Pump the widget into the widget tree.
await tester.pumpWidget(widget);
final button = find.text('Tap me!');
await tester.tap(button);
// Verify that the button was tapped.
expect(completer.isCompleted, equals(true));
});
});
}
To run the test, simply type
flutter test
in the terminal.In my "Make A Widget Clickable" article, I provide a more real-world example of how a widget test might look.
Integration testing
Integration testing is a type of testing that focuses on testing the interactions between different parts of an application. Integration tests are typically written to verify that the application works as a whole, and that different components of the application can communicate with each other correctly.
There is a great cookbook which lays out the steps required to write your first integration tests. As there are a few steps involved to get set up, I'd rather not duplicate what the cookbook does a great job of doing anyway!
Conclusion
If you are of the writing tests camp, then doing so is really easy with Flutter, and is very similar to what you can expect from most testing frameworks. The only thing I found interesting was the lack of a built in way to mock callbacks (think
jest.fn()
when using jest
to test JavaScript code), but this is beautifully covered by Mockito.