Fixing The Past

If you’ve been following along my posts, you’ll remember that in the last post the Travis build failed with some errors:

The first of it is basically complaining about the index field not being final in the ChatItemWidget class. So let’s do that.

final int index;

Second error is about the missing onClick param in InputWidget. Let’s add a blank onClick action for the emoji button for now.

onPressed: (){},

Another error we had was with the overflowing of pixels. I figured out that this is because we used static heights/widths at some places. Not the best thing to do. So I’ve replaced them with combination of flex property with Expanded Widget. Checkout the full code in the Code Changes section.

Also, get rid of the Hello World test from the widget_test.dart file and rename it to main_test.dart for the sake of clarity. We now have a clean slate and are ready to write our first set of UI tests !

Let’s Get Started

Quoting from the official Testing Flutter Apps Guide. Here’s what a widget test is:

A widget test (in other UI frameworks referred to as component test) tests a single widget. The goal of a widget test is to verify that the widget’s UI looks and interacts as expected.

We’ll write tests for all the widgets we created in the last post one by one. For testing Flutter Widgets, you’ll need the flutter_test package. Add it to your dev dependencies

All the test files in flutter should end with _test.dart . We’ll use the testWidgets() method from the flutter_test package to test the widgets. The testWidgets() method provides us with a WidgetTester instance. We use this WidgetTester to pump/load the widgets. In today’s post we’ll be testing the correct rendering of each individual Widget.

The Entry Point

The first thing we’re gonna test is the entry point to the app, the main.dart file. The main.dart renders our app’s main widget Messio , and so we need to import and pump it. The main widget contains one widget in it’s body which is ConversationPageList .

Let me explain the key takeaways from this test one by one:

await keyword is used so that the test waits for the widget to load and only once its loaded, moves on and executes the next line.

keyword is used so that the test waits for the widget to load and only once its loaded, moves on and executes the next line. expect() method is part of the flutter_test package. It takes two arguments, a Finder and a Matcher .

method is part of the package. It takes two arguments, a and a . The Finder defines what exactly we’re trying to find in the UI. It can be find.byType , find.text and many more.

defines what exactly we’re trying to find in the UI. It can be , and many more. The Matcher is the second argument in the expect function and it defines the number of instances we’re expecting to find. It can be findsOneWidget , findsNWidget , findsWidget and findsNothing .

We have the basics clear now. Let’s go ahead and write the tests for rest of the app.

Page Tests

After the entry point, the next level of widgets is the pages. We have two of them.

ConversationPageList

The ConversationPageList Widget has a PageView in its body, which then has multiple ConversationPage Widgets. At a time only one ConversationPage widget is visible on the screen. The WidgetTester tests only the elements visible on the screen and that’s the reason why we check for only one instance of ConversationPage .

ConversationPage

The ConversationPage widget has three widgets, the AppBarWidget , the ChatListWidget , and the InputWidget . There is one instance of each present.

Individual Widgets

Lets take a look at the tests for the individual widgets now.

ChatAppBar

ChatAppBar contains the name , username , IconButton , and the CircleAvatar . Do note that for now we have hardcoded the username and name in both the widget and the test, this is because these are just UI rendering tests. We’ll later be writing more meaningful test cases when we have real data to show and business logic to deal with.

ChatItem

The ChatItem is a single row of message. Here we’re testing for the rendering of the number of basic flutter widgets visible. We know from the code that we have 3 Container , 1 Column , 2 Row and 2 Text widgets in a single row. We’re testing for the rendering of the same.

ChatListWidget

ChatListWidget contains a single ListView item.

InputWidget

The InputWidget has two IconButtons i.e. Emoji & Send. The single EditableText Widget is used for entering text.

We’re finished with the tests. Commit the code and all the tests should pass without issues.

That’s it for today. Should you need more details on Widget Testing you can refer this excellent intro from the Flutter Cookbook. Tomorrow we’ll start working on the UI for the page where all the conversations will be displayed in a list. Stay Tuned!

Code Changes

#4 Tests for Conversation Page

How Can You Contribute?

Open issues with suggestion of better approaches or ideas for the app.

Connect with me on Twitter or Linkedin or Instagram.

Star the Github repository.

Share the series on Twitter.

Follow me on Github.

Posts In This Series

Show Your Support

Press the clap button below if you liked reading this post. The more you clap the more it motivates me to write better!