How to do test your Flutter app

  • This tutorial requires you need to know BloC knowledge. If not, please read this document first.
  • Unit test: tests a single function, method, or class.
  • Widget test: (in other UI frameworks referred to as component test) tests a single widget.
  • Integration test: tests a complete app or a large part of an app.
https://flutter.dev/docs/testing
App structure
  • Which class you want to test: utils.dart
  • What method you want to test: isValidEmail
  • What input: trongdth@gmail.com
  • What output you expected: true
import 'package:flutter_bloc_back4app/helpers/utils.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
test('test email valid returns true', () {
/*
input: trongdth@gmail.com
expected: true
*/
var email = 'trongdth@gmail.com';
var actual = Utils.isValidEmail(email);
var expected = true;
expect(actual, expected);
});
}
  • When you create a new futter project. There is a sample code which has widget_test.dart under test folder. The code looks like this:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:tokoin_wallet/main.dart';

void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();

// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
  • Let's go through the code to understand what it does:
await tester.pumpWidget(MyApp()); // Load MyApp widget for testingexpect(find.text('0'), findsOneWidget); // use global object 'find' to find the widget has text '0'. The expectation is 'findsOneWidget'expect(find.text('1'), findsNothing); // use global object 'find' to find the widget has text '1'. The expectation is 'findsNothing'await tester.tap(find.byIcon(Icons.add)); // try to send the 'tap' action to the Icon widget which has 'Icons.add'await tester.pump(); // call 'build' function of the MyApp widgetexpect(find.text('0'), findsNothing); // use global object 'find' to find the widget has text '0'. The expectation is 'findsNothing'expect(find.text('1'), findsOneWidget); // use global object 'find' to find the widget has text '1'. The expectation is 'findsOneWidget'
  • Which widget you want to test: login.dart
  • Your scenario: based on app structure, if user logins unsuccessfully, you are still in the login page instead of the home page.
  • Create an abstract BaseUserRepository class:
abstract class BaseUserRepository {
Future<ParseUser> authenticate({@required String username, @required String email, @required String password,});
Future<ParseUser> signup({@required String username, @required String email, @required String password, });
Future<ParseUser> currentUser();
Future<bool> logout();
}
  • Create MockUserRepository extends from BaseUserRepository
class MockUserRepository extends BaseUserRepository {
ParseUser user;
bool isLogout;
MockUserRepository(); @override
Future<ParseUser> authenticate({String username, String email, String password}) {
var completer = new Completer<ParseUser>();
// At some time you need to complete the future:
completer.complete(user);
return completer.future;
}
@override
Future<ParseUser> currentUser() {
var completer = new Completer<ParseUser>();
// At some time you need to complete the future:
completer.complete(user);
return completer.future;
}
@override
Future<bool> logout() {
var completer = new Completer<bool>();
// At some time you need to complete the future:
completer.complete(isLogout);
return completer.future;
}
@override
Future<ParseUser> signup({String username, String email, String password}) {
var completer = new Completer<ParseUser>();
// At some time you need to complete the future:
completer.complete(user);
return completer.future;
}
}
  • Write a test:
Widget makeWidgetTestable({Widget child, LoginBloc loginBloc}) {
return MaterialApp(
home: BlocProvider<LoginBloc>(
builder: (context) {
return loginBloc;
},
child: child,
),
);
}
MockUserRepository mockUserRepository = MockUserRepository(); 
LoginBloc _loginBloc = LoginBloc(authBloc: AuthBloc(userRepository: mockUserRepository), userRepository: mockUserRepository);
LoginScreen screen = LoginScreen();
await tester.pumpWidget(makeWidgetTestable(child: screen, loginBloc: _loginBloc));
_loginBloc.dispatch(LoginButtonPressed(
username: 'trongdth',
email: 'trongdth@gmail.com',
password: '123456'
));
await tester.pump();
final loginKey = Key('BtnLogin');
expect(find.byKey(loginKey), findsOneWidget);
flutter test
  • Serverless: you (a mobile developer) can control your data, not depend on Backend and DevOps anymore.
  • Pricing: cheaper than AWS.
  • Push notification: send push notification at scale.

--

--

--

I’m a peaceful person who wants to make friend with people around the world.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Procedural Sword Generation

Milvus 2.0 — A Glimpse at New Features

Kubernetes Pod Operator with Persistent Volume for DBT CI-CD in Cloud Composer

Google Summer of Code’18 with AOSSIE

Maps (Dictionaries) in Dart Programming Language

ThreadHold With Otsu

ThreadHold With Otsu

CS373 Spring 2022: Week 14 Ting-Yin Chang Chien

Price estimate for web and mobile applications

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Trong Dinh Thai Hoang

Trong Dinh Thai Hoang

I’m a peaceful person who wants to make friend with people around the world.

More from Medium

Frequently asked: Flutter Interview Questions and Answers

Flutter Pagination With Caching data (SQLite database) — Part 2

The easiest way to build a Flutter iOS app using GitHub Actions, plus a key takeaway for developers

How to convert the Flutter project to null safety without hassle