Flutter is a cross-platform application development framework. But no application is really complete without a comprehensive testing suite. In this article, I will tell you the basic principles of both unit- and widget-testing Flutter apps.
Testing is vital when developing any serious software project. With a good test suite in place, you can make changes to any part of the code without worrying if that is going to break anything. With tests, you can run them any time and get an answer within minutes if the system is working correctly. If you, as a developer do not test your code, how can you expect your clients to test it?
We are going to begin with unit tests, them being the simplest ones. It is important to note that Flutter clearly separates unit tests from widget tests. Where widget tests assert on the widget tree and test the UI, unit tests are not supposed to render the UI and test purely the business logic.
To start testing your classes, you need to add the
test dependency to your
dev_dependencies: test: 1.14.4
Now let’s create a simple model class that we will test:
This is a simple class with 2 properties and a custom getter. Now, create a file
PersonTest.dart in the
This is the simplest test example ever. Firstly, on lines 1-2 we import the
test module and the
Person class that we are about to test. Then, in the
main method, we define a test using the
test function. It will accept the name of the test and a callback function, which executes the test itself. In it, we create the
person model and
person.name will be
test package exposes a number of assertion functions that can be used with
expect(person, isA(Person)) expect(person, isA(String))
Here are some of the common assertions from the
matcher module (built into
Now, if you try running the tests (you can do it with Android Studio, Run -> Run tests), you will see that this test passes. Good job!
Unit tests are pretty simple: perform actions, assert on the results. When UI comes into play, everything becomes complicated. Let’s again write a simplest example possible: a widget that displays your name. We will make sure it renders correctly and shows your name on the screen.
Firstly, let’s create the widget. Add the following to your
Should be nothing surprising here, just a
MyApp stateless widget that requires a named parameter
name. After doing this, add the testing code in
You can see that instead of importing the
test package, we have to import the
flutter_test one. To make it work, make sure you have this in your
dev_dependencies: flutter_test: sdk: flutter
Now, on line 5 note how we use the
testWidgets function instead of the
test. It injects the
WidgetTester object for you that contains some UI fixtures required for rendering. It is also asynchronous, hence the
async keyword for the callback function.
On line 6 we render the UI with the
pumpWidget function. It behaves exactly as you would expect, you simply pass a widget to it. After that, we create a finder, which is used to find widgets in the UI tree. We want to find the text box with the name specified. Lastly, on line 10 we
findsOneWidget. For other cases, you can also assert with
findsWidgets (one or more) or
In this article I explained the foundations of testing Flutter apps, thank you for reading. In the following posts I will go into advanced testing and mocking in Flutter.