Skip to content

Commit

Permalink
Setup patrol integration tests (#2196)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhaledNjim authored Jan 13, 2025
1 parent 3c07a60 commit febdb8c
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 196 deletions.
88 changes: 88 additions & 0 deletions .github/workflows/integration-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"

name: Integration

jobs:
integration_test:
name: Integration Test
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
actions: write
checks: write
pull-requests: write

env:
USERNAME: ${{ secrets.USERNAME }}
PASSWORD: ${{ secrets.PASSWORD }}
SERVER_URL: ${{ secrets.SERVER_URL }}
FLUTTER_VERSION: "3.24.0"
JAVA_VERSION: 17

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
project_id: ${{ secrets.GOOGLE_CLOUD_PROJECT_ID }}
workload_identity_provider: ${{ secrets.GOOGLE_CLOUD_WORKLOAD_IDENTITY_PROVIDER_ID }}
service_account: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT }}

- name: Setup Cloud SDK
uses: google-github-actions/setup-gcloud@v2

- name: Setup flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: "stable"
cache: true
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }}"

- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "temurin"

- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_KEY }}

- name: setup project
run:
flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs

- name: Run Patrol Tests
shell: bash

env:
USERNAME: ${{ secrets.USERNAME }}
PASSWORD: ${{ secrets.PASSWORD }}
SERVER_URL: ${{ secrets.SERVER_URL }}
run: |
dart pub global activate patrol_cli
flutter build apk --config-only
patrol build android \
-v \
--dart-define=USERNAME="$USERNAME" \
--dart-define=SERVER_URL="$SERVER_URL" \
--dart-define=PASSWORD="$PASSWORD"
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 \
--device model=MediumPhone.arm,version=34 \
--timeout 5m \
--use-orchestrator \
--environment-variables clearPackageData=true
6 changes: 6 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ android {
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: "true"
}

signingConfigs {
Expand All @@ -75,6 +77,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
testOptions {
execution "ANDROIDX_TEST_ORCHESTRATOR"
}
}

flutter {
Expand All @@ -88,6 +93,7 @@ dependencies {
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'androidx.multidex:multidex:2.0.1'
androidTestUtil "androidx.test:orchestrator:1.5.1"
}

apply plugin: 'com.google.gms.google-services'
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package app.twake.android.chat;

import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import pl.leancode.patrol.PatrolJUnitRunner;

@RunWith(Parameterized.class)
public class MainActivityTest {
@Parameters(name = "{0}")
public static Object[] testCases() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
// replace "MainActivity.class" with "io.flutter.embedding.android.FlutterActivity.class"
// if in AndroidManifest.xml in manifest/application/activity you have
// android:name="io.flutter.embedding.android.FlutterActivity"
instrumentation.setUp(MainActivity.class);
instrumentation.waitForPatrolAppService();
return instrumentation.listDartTests();
}

public MainActivityTest(String dartTestName) {
this.dartTestName = dartTestName;
}

private final String dartTestName;

@Test
public void runDartTest() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
instrumentation.runDartTest(dartTestName);
}
}
34 changes: 34 additions & 0 deletions docs/adr/0025-add-patrol-integration-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 25. Add patrol integration tests

Date: 2024-12-24

## Status

**Accepted**

## Context

- The need for integration tests to handle real scenarios
- The need to handle interactions with native views in tests such as notification popups or webviews
- Mocking matrix's behaviour using mockito causes a lot of unexpected issues

## Decision

- Add integration tests using Patrol

### Why Patrol?

- Native Interaction: Patrol offers reliable tools for interacting with native views such as
notification popups, platform alerts, or webviews—functionality that can otherwise be cumbersome
with basic Flutter integration tests.
- Reduced Unpredictability: Since Patrol focuses on real-device or simulator-based tests, it helps
reduce the unpredictability that can arise from heavy mocking with tools like Mockito.
## Consequences

- Setup patrol locally:
- Run `dart pub global activate patrol_cli` to enable Patrol CLI
- Run tests locally:
- to run tests we use `patrol test -t path/to/test --dart-define=arg1='value' `
- to run tests in dev mode this will enable hot restarting the tests we
use : `patrol develop -t path/to/test --dart-define=arg1='value' `
arguments are passed for each test using `dart-define` as shown above
193 changes: 0 additions & 193 deletions integration_test/app_test.dart

This file was deleted.

15 changes: 15 additions & 0 deletions integration_test/base/base_scenario.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

abstract class BaseScenario {
final PatrolIntegrationTester $;

const BaseScenario(this.$);

Future<void> execute();

Future<void> expectViewVisible(PatrolFinder patrolFinder) async {
await $.waitUntilVisible(patrolFinder);
expect(patrolFinder, findsWidgets);
}
}
Loading

0 comments on commit febdb8c

Please sign in to comment.