Skip to content

Commit f63c465

Browse files
authored
[testing_app] Migrate the sample to the integration_test package (#633)
1 parent d16d35e commit f63c465

File tree

15 files changed

+301
-626
lines changed

15 files changed

+301
-626
lines changed

testing_app/README.md

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ would do.
1212
Show how to perform:
1313

1414
- Widget Testing,
15-
- Flutter Driver(Integration) Testing,
15+
- Integration Testing,
1616
- Performance Testing, and
1717
- State Management Testing using the [Provider][] package.
1818

@@ -27,20 +27,15 @@ The Flutter SDK can run unit tests and widget tests in a virtual machine, withou
2727
### To run tests on a physical device/emulator:
2828
- Widget Tests:
2929
- Run `flutter run test/<file_path>`
30-
- Flutter Driver Tests:
31-
- Run `flutter drive --target=test_driver/<file_path>`
32-
- eg. `flutter drive --target=test_driver/app.dart` to run the test in `test_driver/app_test.dart`
30+
- Integration Tests:
31+
- Run `flutter drive --driver=integration_test/driver.dart --target=integration_test/app_test.dart`
3332
- Performance Tests:
34-
- Run `flutter drive --target=test_driver/app.dart --driver test_driver/perf_test.dart --profile --trace-startup`
33+
- Run `flutter drive --driver=integration_test/driver.dart --target=integration_test/perf_test.dart --profile --trace-startup`
3534
- Using a physical device and running performance tests in profile mode is recommended.
3635
- The `--trace-startup` option is used to avoid flushing older timeline events when the timeline gets long.
37-
- [E2E](https://pub.dev/packages/e2e) Tests:
38-
- Run `flutter drive --target test/perf_test_e2e.dart --driver test_driver/e2e_test.dart --profile`
39-
- Similar to the above but the test is driven on device.
40-
- You may also reference [E2E manual](https://github.com/flutter/plugins/tree/master/packages/e2e#firebase-test-lab) for how to run such test on Firebase Test Lab.
4136
- State Management Tests:
42-
- For testing state using Flutter Driver
43-
- Run `flutter drive --target=test_driver/<file_path>`
37+
- For testing state using Flutter Integration Tests
38+
- Run `flutter drive --driver=integration_test/driver.dart --target=integration_test/state_mgmt_test.dart`
4439

4540
### To generate test coverage report:
4641
- Install the `lcov` tool:
@@ -53,9 +48,9 @@ The Flutter SDK can run unit tests and widget tests in a virtual machine, withou
5348
- Open `coverage/index/index.html` in your preferred browser.
5449

5550
### CI/CD
56-
- Refer [.travis.yml](../.travis.yml) and the [tool](../tool) directory to see how to test Flutter projects using Travis-CI.
51+
- Refer [.github](../.github) and the [tool](../tool) directory to see how to test Flutter projects using GitHub Actions.
5752

58-
Note that we aren't performing Flutter Driver tests using the Travis tool in this repo. That is because it's recommended to use physical devices to run Driver tests. You can use [Firebase Test Lab](https://firebase.google.com/docs/test-lab), [Codemagic](https://codemagic.io/) or any platform of your choice to do that.
53+
Note that tools like GitHub Actions can't run tests on a physical device, which is required to run integration tests. Instead, you can use [Firebase Test Lab](https://firebase.google.com/docs/test-lab), [Codemagic](https://docs.codemagic.io/testing/aws/) or any platform of your choice to do that.
5954

6055
## Questions/issues
6156

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2020 The Flutter team. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:integration_test/integration_test.dart';
8+
import 'package:testing_app/main.dart';
9+
10+
void main() {
11+
group('Testing App Driver Tests', () {
12+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
13+
14+
testWidgets('Finding an item in the list', (tester) async {
15+
await tester.pumpWidget(TestingApp());
16+
17+
// Create variables for finders that are used multiple times.
18+
final itemFinder = find.byKey(ValueKey('text_25'));
19+
20+
// Scroll until the item to be found appears.
21+
await tester.scrollUntilVisible(
22+
itemFinder,
23+
500.0,
24+
);
25+
26+
// Check if the item contains the correct text.
27+
expect(tester.widget<Text>(itemFinder).data, 'Item 25');
28+
});
29+
30+
testWidgets('Testing IconButtons', (tester) async {
31+
await tester.pumpWidget(TestingApp());
32+
33+
// Create a finder for the icon.
34+
final iconFinder = find.byKey(ValueKey('icon_0'));
35+
36+
// Tap on the icon.
37+
await tester.tap(iconFinder);
38+
await tester.pumpAndSettle(Duration(seconds: 1));
39+
40+
// Verify if appropriate message appears.
41+
expect(find.text('Added to favorites.'), findsOneWidget);
42+
43+
// Tap on the icon again.
44+
await tester.tap(iconFinder);
45+
await tester.pumpAndSettle(Duration(seconds: 1));
46+
47+
// Verify if appropriate message appears.
48+
expect(find.text('Removed from favorites.'), findsOneWidget);
49+
await tester.pumpAndSettle(Duration(seconds: 1));
50+
});
51+
52+
testWidgets('Verifying whether item gets added to favorites',
53+
(tester) async {
54+
await tester.pumpWidget(TestingApp());
55+
56+
// Add item to favorites.
57+
await tester.tap(find.byKey(ValueKey('icon_5')));
58+
await tester.pumpAndSettle(Duration(seconds: 1));
59+
60+
// Tap on the favorites button on the AppBar.
61+
// The Favorites List should appear.
62+
await tester.tap(find.text('Favorites'));
63+
await tester.pumpAndSettle();
64+
65+
// Check if the added item has appeared in the list.
66+
expect(tester.widget<Text>(find.byKey(ValueKey('favorites_text_5'))).data,
67+
equals('Item 5'));
68+
});
69+
70+
testWidgets('Testing remove button', (tester) async {
71+
await tester.pumpWidget(TestingApp());
72+
73+
// Add item to favorites.
74+
await tester.tap(find.byKey(ValueKey('icon_5')));
75+
await tester.pumpAndSettle(Duration(seconds: 1));
76+
77+
// Navigate to Favorites screen.
78+
await tester.tap(find.text('Favorites'));
79+
await tester.pumpAndSettle();
80+
81+
// Tap on the remove icon.
82+
await tester.tap(find.byKey(ValueKey('remove_icon_5')));
83+
await tester.pumpAndSettle();
84+
85+
// Verify if it disappears.
86+
expect(find.text('Item 5'), findsNothing);
87+
88+
// Verify if appropriate message appears.
89+
expect(find.text('Removed from favorites.'), findsOneWidget);
90+
});
91+
});
92+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2020 The Flutter team. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:integration_test/integration_test_driver.dart';
6+
7+
Future<void> main() {
8+
return integrationDriver(
9+
responseDataCallback: (data) async {
10+
// If the tests reported any data, save it to the disk.
11+
if (data != null) {
12+
for (var entry in data.entries) {
13+
print('Writing ${entry.key} to the disk.');
14+
// Default storage destination is the 'build' directory.
15+
await writeResponseData(
16+
entry.value as Map<String, dynamic>,
17+
testOutputFilename: entry.key,
18+
);
19+
}
20+
}
21+
},
22+
);
23+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright 2020 The Flutter team. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:integration_test/integration_test.dart';
8+
import 'package:testing_app/main.dart';
9+
10+
void main() {
11+
group('Testing App Performance Tests', () {
12+
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
13+
as IntegrationTestWidgetsFlutterBinding;
14+
15+
// The fullyLive frame policy simulates
16+
// the way Flutter responds to animations.
17+
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
18+
19+
testWidgets('Scrolling test', (tester) async {
20+
await tester.pumpWidget(TestingApp());
21+
22+
// Create variables for finders that are used multiple times.
23+
final listFinder = find.byType(ListView);
24+
final scroller = tester.widget<ListView>(listFinder).controller;
25+
26+
// Record the performance timeline of the following operations.
27+
await binding.traceAction(
28+
() async {
29+
// Record the performance summary as the app scrolls through
30+
// the list of items.
31+
await binding.watchPerformance(
32+
() async {
33+
// Quickly scroll all the way down.
34+
await scroller.animateTo(
35+
7000,
36+
duration: const Duration(seconds: 1),
37+
curve: Curves.linear,
38+
);
39+
await tester.pumpAndSettle();
40+
41+
// Quickly scroll back up all the way.
42+
await scroller.animateTo(
43+
-7000,
44+
duration: const Duration(seconds: 1),
45+
curve: Curves.linear,
46+
);
47+
await tester.pumpAndSettle();
48+
},
49+
// Send the performance summary to the driver.
50+
reportKey: 'scrolling_summary',
51+
);
52+
},
53+
// Send the timeline data to the driver.
54+
// This timeline can be opened in the Chrome browser's tracing tools
55+
// by navigating to chrome://tracing.
56+
reportKey: 'scrolling_timeline',
57+
);
58+
});
59+
60+
testWidgets('Favorites operations test', (tester) async {
61+
await tester.pumpWidget(TestingApp());
62+
63+
// Record the performance timeline of the following operations.
64+
await binding.traceAction(
65+
() async {
66+
// Record the performance summary as operations are performed
67+
// on the favorites list.
68+
await binding.watchPerformance(
69+
() async {
70+
// Create a list of icon keys.
71+
final iconKeys = [
72+
'icon_0',
73+
'icon_1',
74+
'icon_2',
75+
];
76+
77+
// Add first three items to favorites.
78+
for (var icon in iconKeys) {
79+
// Tap onto the icon.
80+
await tester.tap(find.byKey(ValueKey(icon)));
81+
await tester.pumpAndSettle();
82+
83+
// Verify if appropriate message appears.
84+
expect(find.text('Added to favorites.'), findsOneWidget);
85+
}
86+
87+
// Tap onto the favorites button on the AppBar.
88+
// The Favorites List should appear.
89+
await tester.tap(find.text('Favorites'));
90+
await tester.pumpAndSettle();
91+
92+
final removeIconKeys = [
93+
'remove_icon_0',
94+
'remove_icon_1',
95+
'remove_icon_2',
96+
];
97+
98+
// Remove all the items from favorites.
99+
for (final iconKey in removeIconKeys) {
100+
// Tap onto the remove icon.
101+
await tester.tap(find.byKey(ValueKey(iconKey)));
102+
await tester.pumpAndSettle();
103+
104+
// Verify if appropriate message appears.
105+
expect(find.text('Removed from favorites.'), findsOneWidget);
106+
}
107+
},
108+
// Send the performance summary to the driver.
109+
reportKey: 'favorites_operations_summary',
110+
);
111+
},
112+
// Send the timeline data to the driver.
113+
// This timeline can be opened in the Chrome browser's tracing tools
114+
// by navigating to chrome://tracing.
115+
reportKey: 'favorites_operations_timeline',
116+
);
117+
});
118+
});
119+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2020 The Flutter team. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:integration_test/integration_test.dart';
8+
import 'package:provider/provider.dart';
9+
import 'package:testing_app/models/favorites.dart';
10+
import 'package:testing_app/screens/favorites.dart';
11+
12+
Favorites favoritesList;
13+
14+
Widget createFavoritesScreen() => ChangeNotifierProvider<Favorites>(
15+
create: (context) {
16+
favoritesList = Favorites();
17+
return favoritesList;
18+
},
19+
child: MaterialApp(
20+
home: FavoritesPage(),
21+
),
22+
);
23+
24+
void main() {
25+
group('Testing App State Management Tests', () {
26+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
27+
28+
testWidgets('Verifying add method', (tester) async {
29+
await tester.pumpWidget(createFavoritesScreen());
30+
31+
// Add an item to the list.
32+
favoritesList.add(30);
33+
await tester.pumpAndSettle();
34+
35+
// Check if the new item appears in the list.
36+
expect(find.text('Item 30'), findsOneWidget);
37+
});
38+
39+
testWidgets('Verifying remove method', (tester) async {
40+
await tester.pumpWidget(createFavoritesScreen());
41+
42+
// Remove an item from the list.
43+
favoritesList.remove(30);
44+
await tester.pumpAndSettle();
45+
46+
// Verify if it disappears.
47+
expect(find.text('Item 30'), findsNothing);
48+
});
49+
});
50+
}

testing_app/pubspec.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,6 @@ packages:
106106
url: "https://pub.dartlang.org"
107107
source: hosted
108108
version: "1.0.0"
109-
e2e:
110-
dependency: "direct dev"
111-
description:
112-
name: e2e
113-
url: "https://pub.dartlang.org"
114-
source: hosted
115-
version: "0.7.0+1"
116109
fake_async:
117110
dependency: transitive
118111
description:
@@ -133,7 +126,7 @@ packages:
133126
source: sdk
134127
version: "0.0.0"
135128
flutter_driver:
136-
dependency: "direct dev"
129+
dependency: transitive
137130
description: flutter
138131
source: sdk
139132
version: "0.0.0"
@@ -175,6 +168,13 @@ packages:
175168
url: "https://pub.dartlang.org"
176169
source: hosted
177170
version: "3.1.4"
171+
integration_test:
172+
dependency: "direct dev"
173+
description:
174+
name: integration_test
175+
url: "https://pub.dartlang.org"
176+
source: hosted
177+
version: "1.0.1"
178178
io:
179179
dependency: transitive
180180
description:

testing_app/pubspec.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ dependencies:
1414
provider: ^4.1.3
1515

1616
dev_dependencies:
17+
integration_test: ^1.0.1
1718
flutter_test:
1819
sdk: flutter
19-
flutter_driver:
20-
sdk: flutter
2120
test: ^1.14.4
22-
e2e: ^0.7.0
2321
pedantic: ^1.9.0
2422

2523
flutter:

0 commit comments

Comments
 (0)