-
Notifications
You must be signed in to change notification settings - Fork 35
300 Testing
Page Table of Contents
//Last Snip 36 //Last Fig 23
Testing has become an essential part of developing a large scale application and there is strong evidence that writing tests leads to a higher code quality [71]. This chapter aims to give you a brief introduction to how testing in Flutter [1] works.
Flutters official test library [72] differentiates between three types of tests:
Unit Test can be run very quickly. They can test any function of your app, that does not require the rendering of a Widget [73]. Their main use-case is to test business logic or in our case: BLoCs [7].
Widget Tests are used to test small Widget Sub-Trees of your application. They run relatively quickly and can test the behavior of a given UI [73].
Integration Test/Driver Tests run your entire application in a virtual machine or on a physical device. They can test user-journeys and complete use-cases. They are very slow and “prone to braking”[73].
Figure XXX: Flutter Test Comparison [74]
I will focus on Unit Tests for this guide. The Flutter Team recommends that the majority of Flutter tests should be Unit Test, as they are quick to write, quick to execute and yield relatively high confidence [73], [74]. In addition to this, because we are using the BLoC Pattern, our UI shouldn’t contain that much testable code anyways. Or to paraphrase the BLoC pattern creator: We keep our UI so stupid we don’t need to test it [7]. First we have to import the test library [72] and the mockito package [75] in our pubspec.yaml:
dev_dependencies:
mockito: ^4.1.1
flutter_test:
sdk: flutterCode Snippet XXX: Pubspec.yaml Test Imports
flutter_test offers the core testing capabilities of Flutter, mockito is used to mock up dependencies. Now place a new directory called “tests” on the root level of our app directory:
Figure XXX: Wisgen Test Directory [11]
| ⚠ | All testfiles have to end with the postfix "_test.dart" to be recognized by the framework [73]. |
|---|
Now we can start writing our tests. For this example, I will test the favortie BLoC of Wisgen [11].
void main() {
///Related test are grouped together
///to get a more readable output
group('Favorite Bloc', () {
FavoriteBloc favoriteBloc;
setUp((){
//Run before each test
favoriteBloc = new FavoriteBloc();
});
tearDown((){
//Run after each test
favoriteBloc.dispose();
});
test('Add a Favorite and see if it is emitted as state', () {
//Set Up
Wisdom wisdom = Wisdom(id: 1, text: "Back up your Pictures", type: "tech");
//Testing
favoriteBloc.dispatch(AddFavoriteEvent(wisdom));
//Result
favoriteBloc.state.listen((data) => () {
expect(wisdom, data);
});
});
...
});
}Code Snippet XXX: Wisgen Favorite BLoC Tests 1 [11]
void main() {
group('Favorite Bloc', () {
FavoriteBloc favoriteBloc;
setUp((){...});
tearDown((){...});
test('Add a Favorite and see if it is emitted as state', () {...});
test('Add and Remove a Favorite and see if the state is empty', () {
//Set Up
Wisdom wisdom = Wisdom(id: 1, text: "Back up your Pictures", type: "tech");
//Testing
favoriteBloc.dispatch(AddFavoriteEvent(wisdom));
favoriteBloc.dispatch(RemoveFavoriteEvent(wisdom));
//Result
expect(0, favoriteBloc.currentState.length);
});
...
});
}Code Snippet XXX: Wisgen Favorite BLoC Tests 2 [11]
void main() {
group('Favorite Bloc', () {
FavoriteBloc favoriteBloc;
setUp((){...});
tearDown((){...});
test('Add a Favorite and see if it is emitted as state', () {...});
test('Add and Remove a Favorite and see if the state is empty', () {...});
test('Stream many events and see if the State is emitted in correct order', () {
//Set Up
Wisdom wisdom1 = Wisdom(id: 1, text: "Back up your Pictures", type: "tech");
Wisdom wisdom2 = Wisdom(id: 2, text: "Wash your ears", type: "Mum's Advice");
Wisdom wisdom3 = Wisdom(id: 3, text: "Travel while you're young", type: "Grandma's Advice");
//Testing
favoriteBloc.dispatch(AddFavoriteEvent(wisdom1));
favoriteBloc.dispatch(AddFavoriteEvent(wisdom2));
favoriteBloc.dispatch(RemoveFavoriteEvent(wisdom1));
favoriteBloc.dispatch(AddFavoriteEvent(wisdom3));
//Result
expect(
favoriteBloc.state,
emitsInOrder([
List(), //BLoC Library BLoCs emit their initial State on creation
List()..add(wisdom1),
List()..add(wisdom1)..add(wisdom2),
List()..add(wisdom2),
List()..add(wisdom2)..add(wisdom3)
]));
});
});
}Code Snippet XXX: Wisgen Favorite BLoC Tests 3 [11]
- testing a bloc
- Dependency injection problems in Flutter

This Guide is licensed under the Creative Commons License (Attribution-NoDerivatives 4.0 International)
Author: Sebastian Faust.