As your app gets bigger, a good set of tests may help you save time, as tests can find new bugs that could appear with normal modifications. Even performing Test-Driven Development (TDD) is a good idea, as it can help you define a structure of your project and write less but more efficient code.
In Flutter, there are mainly three kinds of automated testing: unit testing, widget testing, and integration testing. Let’s take a look at them in detail.
Unit Testing
As the name suggests, a unit test is a type of testing that is used to test a single unit of code. This small unit could be a function, method, or class. Generally, with in-unit testing, we won’t need to write on a disk, render to a screen, or receive external input. Unit tests must be as small as possible, so remove any possible external dependencies.
These tests are low maintenance, low in cost and are very quick to execute. The only drawback of unit testing is that you can never completely rely on it, as it does not test the system as a whole. For this reason, there are other kinds of testing that should be used. Let’s take a look at how to perform this type of testing:
- Import pubspec.yaml into your testing framework, as follows:
dev_dependencies:
flutter_test:sdk: flutter
- Write the test code in test/unit_test.dart:
import 'package:test/test.dart';
void main() {test('the answer to the question', () {
var answer = 42;
expect(answer, 42);
}); }
- Run the test by running ‘flutter test test/unit_test.dart’ in the project folder. Alternatively, you can run a ‘flutter test’ to run all the tests.
Unit tests are run in a local Dart VM with a headless version of the Flutter engine. This makes the process faster because it doesn’t need to boot a real Flutter engine or compile a real application.
Widget Testing
Widget testing is also known as component testing. As its name suggests, it is used for testing a single widget, and the goal of this test is to verify whether the widget works and looks as expected.
In addition, you can use the WidgetTester utility for multiple things while testing, such as sending input to a widget, finding a component in the widget tree, verifying values, and so on. Let’s take a look at how a widget test looks in code:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';void main() {
testWidgets('my first widget test', (WidgetTester tester) async {// You can use keys to locate the widget you need to test
var sliderKey = UniqueKey();
var value = 0.0;// Tells the tester to build a UI based on the widget tree passed to it
await tester.pumpWidget(
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return MaterialApp(home: Material(
child: Center(child: Slider(
key: sliderKey,
value: value,
onChanged: (double newValue) {setState(() {
value = newValue;
});},),),),);},),);
expect(value, equals(0.0));// Taps on the widget found by key
await tester.tap(find.byKey(sliderKey));// Verifies that the widget updated the value correctly
expect(value, equals(0.5));});}
While testing, if you need to see the UI, you can always use the debugDumpApp() function or run the test using a flutter tun test/widget_test.dart. In this way, you will also be able to interact with the widgets during testing.
Integration Testing
Now, let’s take a look at integration testing. This type of testing is used for testing the whole application or a big part of the application. Integration testing can be used to verify that the app does everything as expected or to test the performance of the code. Integration tests are run on a real device or an emulator, but they can’t be run with a headless version of Dart VM like as it can in widget testing.
Now, let’s get started with writing and running the tests:
- Add the flutter_driver package to pubspec:
dev_dependencies:
flutter_driver:
sdk: flutter
- Enable the Flutter driver extension and add a call to the enableFlutterDriverExtension() function in main.dart.
- Run the integration test by using the flutter drive command: flutter drive — target=my_app/test_driver/my_test.dart
by Santhosh Adiga | Mobile Developer, CRITICALSTART
September 17, 2019