0Pricing
React Native Academy · บทเรียน

Maestro ใน CI ด้วย GitHub Actions

เพิ่มงานทดสอบ Maestro ในเวิร์กโฟลว์ GitHub Actions เริ่มตัวจำลอง Android ใน CI รันชุดทดสอบ Maestro และอัปโหลดไฟล์ผลลัพธ์เมื่อเกิดความล้มเหลว

Maestro ใน CI ด้วย GitHub Actions เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

Why Run Maestro in CI?

Running Maestro tests locally on your machine catches bugs before you push. Running them in CI (Continuous Integration) catches bugs before they reach main and are seen by other team members. Every pull request can automatically trigger the E2E suite and block merging if any test fails.

GitHub Actions is the most popular CI platform for open-source and small-team projects. It runs workflows defined in YAML files inside .github/workflows/. An Android emulator runs inside a GitHub-hosted Linux runner, while iOS requires a macOS runner.

GitHub Actions Workflow Basics

A GitHub Actions workflow file defines triggers (when to run), jobs (parallel or sequential work units), and steps (individual commands within a job). Each job runs on a fresh virtual machine specified by the runs-on key.

Maestro E2E tests require a running Android emulator or iOS Simulator. Android emulators run on ubuntu-latest runners. iOS Simulators require macos-latest runners, which are more expensive in GitHub Actions minutes.

# .github/workflows/e2e.yml
name: E2E Tests

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main]

jobs:
  e2e-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Maestro E2E Tests
        run: echo 'Steps to follow...'

Starting an Android Emulator in CI

The reactivecircus/android-emulator-runner GitHub Action starts an Android Virtual Device (AVD) inside the CI runner, runs your commands with the emulator available, and shuts it down after. It handles AVD creation, booting, and waiting for the device to be ready.

Choose a recent API level (api-level: 33 is Android 13) and set target: google_apis if your app uses Google Play Services or Google Maps. The emulator boot can take 2-5 minutes on GitHub's shared runners, so budget for this in your CI time estimates.

jobs:
  e2e-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Enable KVM (hardware acceleration)
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Run Android Emulator
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 33
          arch: x86_64
          script: echo 'Emulator is ready'

Installing Maestro in CI

Install the Maestro CLI in the CI runner before running tests. Add the installation step to your workflow. Maestro's install script downloads the binary and adds it to the PATH.

After installation, verify the CLI is available with maestro --version. Add ~/.maestro/bin to the PATH environment variable for the rest of the workflow steps to find the binary.

      - name: Install Maestro CLI
        run: |
          curl -Ls 'https://get.maestro.mobile.dev' | bash
          echo '$HOME/.maestro/bin' >> $GITHUB_PATH

      - name: Verify Maestro installation
        run: maestro --version

Building and Installing the APK

Before Maestro can test the app, the APK (Android Package) must be built and installed on the emulator. Build the debug APK with Gradle and install it with adb install. For Expo apps, use EAS Build or npx expo run:android --variant release locally and commit the resulting APK as a build artifact.

To speed up CI, cache the Gradle build artifacts between runs using actions/cache. This reduces the build step from 5-10 minutes to 1-2 minutes on subsequent runs.

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build Debug APK
        run: cd android && ./gradlew assembleDebug

      - name: Install APK on emulator
        run: adb install android/app/build/outputs/apk/debug/app-debug.apk

Running the Maestro Test Suite

Run all Maestro flows with maestro test pointing to your flows directory. Use the --format flag to produce a JUnit XML report that GitHub Actions can display in the pull request UI as a test summary.

Pass environment variables from GitHub Secrets using -e KEY=${{ secrets.KEY }}. Store test account credentials in GitHub Secrets (Settings > Secrets) to keep them out of your repository code.

      - name: Run Maestro E2E Tests
        env:
          TEST_EMAIL: ${{ secrets.E2E_TEST_EMAIL }}
          TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }}
        run: |
          maestro test \
            -e TEST_EMAIL=$TEST_EMAIL \
            -e TEST_PASSWORD=$TEST_PASSWORD \
            --format junit \
            --output test-results.xml \
            maestro/flows/

Uploading Test Results and Screenshots

Use actions/upload-artifact to save the JUnit XML report and Maestro's failure screenshots as CI artifacts. These are available for download from the GitHub Actions run page for 90 days. When a test fails, download the artifacts to see exactly which screen the test was on when it failed.

Run the upload step with if: always() so it executes even when the test job fails. Without this, a failing test would prevent the artifact upload and you would have no debugging information.

      - name: Upload test results
        if: always()  # Upload even if tests fail
        uses: actions/upload-artifact@v4
        with:
          name: e2e-test-results
          path: |
            test-results.xml
            ~/.maestro/tests/
          retention-days: 30

      - name: Publish Test Report
        if: always()
        uses: mikepenz/action-junit-report@v4
        with:
          report_paths: 'test-results.xml'
          check_name: 'E2E Test Results'

Caching Dependencies for Speed

The biggest time cost in a CI E2E job is usually installing Node modules, building the app, and booting the emulator. Cache node_modules between runs to skip npm install on every push. Cache the Android Gradle build to skip recompiling unchanged native code.

Use a cache key that includes a hash of your package-lock.json so the cache is invalidated when dependencies change. A well-cached job reduces from 20 minutes to under 10 minutes for most React Native projects.

      - name: Cache Node modules
        uses: actions/cache@v4
        with:
          path: node_modules
          key: node-${{ hashFiles('package-lock.json') }}
          restore-keys: node-

      - name: Cache Gradle
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
            android/.gradle
          key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: gradle-

Running Maestro on iOS in CI

iOS E2E tests require a macOS runner because iOS Simulators only run on macOS. Use runs-on: macos-latest and select the simulator with xcrun simctl. Boot the simulator before installing the app and running Maestro.

iOS CI jobs are 10x more expensive in GitHub Actions minutes than Linux jobs. Run iOS E2E only on PRs to main or on a scheduled nightly build, not on every push to feature branches.

  e2e-ios:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Start iOS Simulator
        run: |
          xcrun simctl boot 'iPhone 16'
          open -a Simulator

      - name: Install dependencies
        run: npm ci

      - name: Build iOS app
        run: npx expo run:ios --configuration Release --no-bundler

      - name: Install Maestro
        run: curl -Ls 'https://get.maestro.mobile.dev' | bash && echo '$HOME/.maestro/bin' >> $GITHUB_PATH

      - name: Run E2E Tests
        run: maestro test maestro/flows/ --format junit --output ios-results.xml

Handling Flaky Tests in CI

Flaky tests — tests that sometimes pass and sometimes fail with no code changes — are a major CI reliability problem. Common causes in Maestro are: animations not finishing before assertions, slow emulator performance in CI, and network-dependent tests that fail on timeouts.

Strategies to reduce flakiness: use waitForAnimationToEnd generously, increase assertion timeouts on network-dependent steps, use clearState: true to ensure each test starts clean, and mock the backend API with a test server so responses are instant and deterministic.

# Add retry logic at the workflow level for flaky suites
      - name: Run Maestro (with retry)
        uses: nick-fields/retry@v3
        with:
          timeout_minutes: 15
          max_attempts: 2
          command: |
            maestro test \
              --format junit \
              --output test-results.xml \
              maestro/flows/

Integrating with Maestro Cloud

Maestro Cloud (cloud.mobile.dev) is a hosted service by the Maestro team that runs your E2E tests on real devices without requiring you to manage emulators in CI. You push your app binary and flow files, and Maestro Cloud runs them on a fleet of real iOS and Android devices.

Integrate Maestro Cloud into GitHub Actions with the mobile-dev-inc/action-maestro-cloud action. It handles device provisioning, test execution, and result reporting. Real device testing catches device-specific bugs that emulators miss.

      - name: Upload to Maestro Cloud
        uses: mobile-dev-inc/action-maestro-cloud@v1
        with:
          api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
          app-file: android/app/build/outputs/apk/debug/app-debug.apk
          workspace: maestro/flows/
          env: |
            TEST_EMAIL=${{ secrets.E2E_TEST_EMAIL }}
            TEST_PASSWORD=${{ secrets.E2E_TEST_PASSWORD }}

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: how to write a GitHub Actions workflow that starts an Android emulator, installs Maestro, and runs E2E flows automatically on pull requests, how to cache node_modules and Gradle artifacts to speed up CI runs, and how to upload test results and failure screenshots as artifacts for post-failure debugging. Congratulations on completing the E2E Testing with Maestro course — your app now has a complete testing pyramid from unit tests through end-to-end flows.

คำถามที่พบบ่อย

บทเรียน “Maestro ใน CI ด้วย GitHub Actions” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Maestro ใน CI ด้วย GitHub Actions” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Maestro ใน CI ด้วย GitHub Actions”

เพิ่มงานทดสอบ Maestro ในเวิร์กโฟลว์ GitHub Actions เริ่มตัวจำลอง Android ใน CI รันชุดทดสอบ Maestro และอัปโหลดไฟล์ผลลัพธ์เมื่อเกิดความล้มเหลว คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “Maestro ใน CI ด้วย GitHub Actions” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม

ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การติดตั้ง Maestro และรันโฟลว์แรก
  2. การตรวจสอบและการรอองค์ประกอบ
  3. การทดสอบเส้นทางการใช้งานหลายหน้าจอ
  4. Maestro ใน CI ด้วย GitHub Actions
← กลับไปที่ React Native Academy