2020-11-06 01:28:47 +00:00
# integration_test
This package enables self-driving testing of Flutter code on devices and emulators.
It adapts flutter_test results into a format that is compatible with `flutter drive`
and native Android instrumentation testing.
## Usage
Add a dependency on the `integration_test` and `flutter_test` package in the
`dev_dependencies` section of `pubspec.yaml` . For plugins, do this in the
2021-04-08 22:39:03 +00:00
`pubspec.yaml` of the example app:
```yaml
integration_test:
sdk: flutter
```
2020-11-06 01:28:47 +00:00
Create a `integration_test/` directory for your package. In this directory,
create a `<name>_test.dart` , using the following as a starting point to make
assertions.
```dart
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
2021-01-16 04:05:10 +00:00
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
2020-11-06 01:28:47 +00:00
testWidgets("failing test example", (WidgetTester tester) async {
expect(2 + 2, equals(5));
});
}
```
### Driver Entrypoint
An accompanying driver script will be needed that can be shared across all
integration tests. Create a file named `integration_test.dart` in the
`test_driver/` directory with the following contents:
```dart
import 'package:integration_test/integration_test_driver.dart';
Future< void > main() => integrationDriver();
```
You can also use different driver scripts to customize the behavior of the app
under test. For example, `FlutterDriver` can also be parameterized with
different [options ](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/connect.html ).
See the [extended driver ](https://github.com/flutter/plugins/tree/master/packages/integration_test/example/test_driver/integration_test_extended_driver.dart ) for an example.
### Package Structure
Your package should have a structure that looks like this:
```
lib/
...
integration_test/
foo_test.dart
bar_test.dart
test/
# Other unit tests go here.
test_driver/
integration_test.dart
```
[Example ](https://github.com/flutter/plugins/tree/master/packages/integration_test/example )
## Using Flutter Driver to Run Tests
These tests can be launched with the `flutter drive` command.
To run the `integration_test/foo_test.dart` test with the
`test_driver/integration_test.dart` driver, use the following command:
```sh
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/foo_test.dart
```
### Web
Make sure you have [enabled web support ](https://flutter.dev/docs/get-started/web#set-up )
then [download and run ](https://flutter.dev/docs/cookbook/testing/integration/introduction#6b-web )
the web driver in another process.
Use following command to execute the tests:
```sh
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/foo_test.dart \
-d web-server
```
## Android Device Testing
Create an instrumentation test file in your application's
**android/app/src/androidTest/java/com/example/myapp/** directory (replacing
com, example, and myapp with values from your app's package name). You can name
this test file `MainActivityTest.java` or another name of your choice.
```java
package com.example.myapp;
import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import org.junit.Rule;
import org.junit.runner.RunWith;
@RunWith (FlutterTestRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule< MainActivity > rule = new ActivityTestRule< >(MainActivity.class, true, false);
}
```
Update your application's **myapp/android/app/build.gradle** to make sure it
uses androidx's version of `AndroidJUnitRunner` and has androidx libraries as a
dependency.
```gradle
android {
...
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
testImplementation 'junit:junit:4.12'
// https://developer.android.com/jetpack/androidx/releases/test/#1.2.0
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
```
To run `integration_test/foo_test.dart` on a local Android device (emulated or
physical):
```sh
./gradlew app:connectedAndroidTest -Ptarget=`pwd`/../integration_test/foo_test.dart
```
## Firebase Test Lab
If this is your first time testing with Firebase Test Lab, you'll need to follow
the guides in the [Firebase test lab
documentation](https://firebase.google.com/docs/test-lab/?gclid=EAIaIQobChMIs5qVwqW25QIV8iCtBh3DrwyUEAAYASAAEgLFU_D_BwE)
to set up a project.
To run a test on Android devices using Firebase Test Lab, use gradle commands to build an
instrumentation test for Android, after creating `androidTest` as suggested in the last section.
```bash
pushd android
# flutter build generates files in android/ for building the app
flutter build apk
./gradlew app:assembleAndroidTest
./gradlew app:assembleDebug -Ptarget=< path_to_test > .dart
popd
```
Upload the build apks Firebase Test Lab, making sure to replace < PATH_TO_KEY_FILE > ,
< PROJECT_NAME > , < RESULTS_BUCKET > , and < RESULTS_DIRECTORY > with your values.
```bash
gcloud auth activate-service-account --key-file=< PATH_TO_KEY_FILE >
gcloud --quiet config set project < PROJECT_NAME >
gcloud firebase test android run --type instrumentation \
--app build/app/outputs/apk/debug/app-debug.apk \
--test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk\
--timeout 2m \
--results-bucket=< RESULTS_BUCKET > \
--results-dir=< RESULTS_DIRECTORY >
```
You can pass additional parameters on the command line, such as the
devices you want to test on. See
[gcloud firebase test android run ](https://cloud.google.com/sdk/gcloud/reference/firebase/test/android/run ).
## iOS Device Testing
2020-12-07 20:48:03 +00:00
Open `ios/Runner.xcworkspace` in Xcode. Create a test target if you
do not already have one via `File > New > Target...` and select `Unit Testing Bundle` .
2021-01-22 01:26:07 +00:00
Change the `Product Name` to `RunnerTests` . Make sure `Target to be Tested` is set to `Runner` and language is set to `Objective-C` .
2020-12-07 20:48:03 +00:00
Select `Finish` .
2021-01-22 01:26:07 +00:00
Under **Runner** > **Info** > **Configurations** section, make sure, that `Runner` and `RunnerTests` have the same value under each configuration.
Make sure that the **iOS Deployment Target** of `RunnerTests` within the **Build Settings** section is the same as `Runner` .
2020-12-07 20:48:03 +00:00
Add the new test target to `ios/Podfile` by embedding in the existing `Runner` target.
2020-11-06 01:28:47 +00:00
```
target 'Runner' do
2020-12-07 20:48:03 +00:00
# Do not change existing lines.
2020-11-06 01:28:47 +00:00
...
2020-12-07 20:48:03 +00:00
target 'RunnerTests' do
inherit! :search_paths
end
end
2020-11-06 01:28:47 +00:00
```
2020-12-07 20:48:03 +00:00
Run `flutter build ios` from your project file to hook up the new settings.
2020-11-06 01:28:47 +00:00
2020-12-07 20:48:03 +00:00
In Xcode, add a test file called `RunnerTests.m` (or any name of your choice) to the new target and
replace the file:
2020-11-06 01:28:47 +00:00
```objective-c
2020-12-07 20:48:03 +00:00
@import XCTest;
@import integration_test;
2020-11-06 01:28:47 +00:00
INTEGRATION_TEST_IOS_RUNNER(RunnerTests)
```
2020-12-07 20:48:03 +00:00
Run `Product > Tests` to run the integration tests on your selected device.
To build `integration_test/foo_test.dart` from the command line, run:
```sh
# Pass --simulator if building for the simulator.
flutter build ios integration_test/foo_test.dart
```
2021-01-22 01:26:07 +00:00
To deploy it to Firebase Test Lab you can follow these steps:
Execute this script at the root of your Flutter app:
```sh
output="../build/ios_integ"
2021-01-25 20:16:06 +00:00
product="build/ios_integ/Build/Products"
2021-01-22 01:26:07 +00:00
dev_target="14.3"
# Pass --simulator if building for the simulator.
flutter build ios integration_test/foo_test.dart -release
pushd ios
xcodebuild -workspace Runner.xcworkspace -scheme Runner -config Flutter/Release.xcconfig -derivedDataPath $output -sdk iphoneos build-for-testing
2021-01-25 20:16:06 +00:00
popd
pushd $product
zip -r "ios_tests.zip" "Release-iphoneos" "Runner_iphoneos$dev_target-arm64.xctestrun"
2021-01-22 01:26:07 +00:00
popd
```
2021-04-01 17:04:03 +00:00
You can verify locally that your tests are successful by running the following command:
2021-01-22 01:26:07 +00:00
```sh
xcodebuild test-without-building -xctestrun "build/ios_integ/Build/Products/Runner_iphoneos14.3-arm64.xctestrun" -destination id=< YOUR_DEVICE_ID >
```
Once everything is ok, you can upload the resulting zip to Firebase Test Lab (change the model with your values):
```sh
gcloud firebase test ios run --test "build/ios_integ/ios_tests.zip" --device model=iphone11pro,version=14.1,locale=fr_FR,orientation=portrait
```