Améliorer le délai d’exécution en utilisant Stratégie de travail GitHub
Si vous êtes nouveau dans les tests d’intégration Flutter, je vous suggère d’explorer Tests d’intégration documentation comme condition préalable. Flutter prend en charge une intégration fluide avec Firebase Test Lab. Pour en savoir plus sur l’intégration, veuillez consulter le Suite d’intégration avec Firebase Test Lab.
Firebase Test Lab est une infrastructure de test d’applications basée sur le cloud qui vous permet de tester votre application sur une gamme d’appareils et de configurations, afin que vous puissiez avoir une meilleure idée de ses performances entre les mains des utilisateurs en direct.
Considérons que nous avons 30 flux E2E écrits pour les tests d’intégration Flutter. Le temps d’exécution total pour obtenir des résultats prend environ 30 minutes en moyenne (une minute par flux e2e). J’ai supposé que nous allions bien pendant 30 minutes pour obtenir des commentaires sur les tests d’automatisation.
Mais si nos flux E2E sont passés de 30 à 300, le temps de retour moyen est de cinq heures. C’est trop de temps d’attente.
Une solution qui nous viendra à l’esprit sera de lancer les tests en mode parallèle.
Mais, nous en avons un ouvert publierFirebase Test Lab ne prend pas en charge l’exécution parallèle (sharding des tests) pour Flutter.
J’ai réduit mon délai d’automatisation en utilisant Stratégie de travail GitHub. Je vais détailler mon approche étape par étape.
Étape 1 : Supposons que nous disposions de quatre fichiers de test : feature1_tests.dart
, feature2_tests.dart
, feature3_tests.dart
et feature4_tests.dart
. Chaque fichier aura des cas de widget de test. Chaque fichier de test de fonctionnalité ressemblera à ce qui suit (ayant la méthode principale avec plusieurs cas de test) :
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
as IntegrationTestWidgetsFlutterBinding;
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
group('Feature 1', () {
testWidgets('Scenario 1', (WidgetTester tester) async {});
testWidgets('Scenario 2', (WidgetTester tester) async {});
});
}
Étape 2 : Nous définirons nos suites de tests avec la méthode principale appelant plusieurs fonctionnalités. Dire, Suite1
et Suite2
.
// Suite1.dart File , with feature 1 and Feature 2
import 'tests/feature1_tests.dart' as feature1_tests;
import 'tests/feature2_tests.dart' as feature2_tests;void main() {
feature1_tests.main();
feature2_tests.main();
}
// Suite2.dart File , with feature 3and Feature 4import 'tests/feature3_tests.dart' as feature3_tests;
import 'tests/feature4_tests.dart' as feature4_tests;
void main() {
feature3_tests.main();
feature4_tests.main();
}
Noter: En fonction de votre projet et de vos fonctionnalités, vous pouvez créer votre suite en conséquence.
Étape 3 : Créons notre flux de travail GitHub pour exécuter deux suites en parallèle à l’aide de Stratégie de travail GitHub.
name: Parallel Test Execution On Firebase Test Labon:
workflow_dispatch:
env:
ANDROID_HOME: /Users/runner/Library/Android/sdk
JAVA_HOME: /Users/runner/hostedtoolcache/Java_Microsoft_jdk/11.0.13/x64/Contents/Home
flutter_version: "3.3.9"
jobs:
integration-tests:
runs-on: macos-11
timeout-minutes: 60
continue-on-error: true
strategy: # GitHub Strategy
fail-fast: false
max-parallel: 2
matrix:
tests: [SUITE1,SUITE2]
steps:
- name: Checkout Repository And Submodules
uses: actions/checkout@v2
- id: 'auth'
uses: 'google-github-actions/auth@v0'
with:
service_account: 'Your Service Account Link'
credentials_json: ${{ }}
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v0'
- name: 'Use gcloud CLI'
run: 'gcloud info'
- name: Java Setup
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
# Caching Flutter SDK download based on version
- name: Flutter SDK Download
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.flutter_version }}
channel: 'stable'
cache: true
cache-key: flutterA-${{ env.flutter_version }}
cache-path: ${{ runner.tool_cache }}/flutterA-${{ env.flutter_version }}
- name: Download Flutter Dependencies
run: |
flutter pub get
# Assuming shell script to Run on Firebase is Placed at file location - integration_test/firebase_parallel_test_runner.sh
- name: Assign Permission to shell file
run: |
chmod 777 ./integration_test/firebase_parallel_test_runner.sh
# Passing ${{matrix.tests}} as positional parameter to shell file
# If ${{matrix.tests}} = SUITE1 , we will upload Suite1.dart based test apk and same as SUITE2
- name: Run Suite
run: |
sh .integration_test/firebase_parallel_test_runner.sh ${{matrix.tests}}
Étape 4 : Créez notre script Bash Shell pour exécuter les suites sur Firebase Test Lab. Nous prendrons un paramètre de la ligne de commande ou de la variable GitHub et l’utiliserons pour créer notre APK de test spécifique à cette suite.
# Firebase Test Lab required Gcloud setup on Your MachineDEBUG_APK_PATH=build/app/outputs/flutter-apk/app-debug.apk # File path of debug APk
TEST_APK_PATH=build/app/outputs/apk/androidTest/staging/debug/app-debug-androidTest.apk # File Path of Test Apk
SUITE=$1 # Positional Argument which will give Suite Name i.e SUITE1 and SUITE2 in our case
flutter build apk --debug # Build the Debug APk
pushd android
./gradlew app:assembleAndroidTest
popd
if [ "$SUITE" == "SUITE1" ]; then
pushd android
./gradlew app:assembleDebug -Ptarget=integration_test/suites/suite1.dart
popd
if gcloud firebase test android run --type instrumentation --app $DEBUG_APK_PATH --test $TEST_APK_PATH --timeout 45m
then
exit 0 # Exit with 0 if all test passed else exit with 1
else
exit 1
fi
fi
if [ "$SUITE" == "SUITE2" ]; then
pushd android
./gradlew app:assembleDebug -Ptarget=integration_test/suites/suite2.dart
popd
if gcloud firebase test android run --type instrumentation --app $DEBUG_APK_PATH --test $TEST_APK_PATH --timeout 45m
then
exit 0
else
exit 1
fi
fi
Ouais! Vous êtes prêt. Désormais, vos deux suites fonctionneront en parallèle. Cela minimisera votre délai d’exécution.
Le code source est disponible dans ce Référentiel GitHub.