Mở rộng quy mô kiểm thử bằng các thiết bị do Gradle quản lý

Thiết bị do Gradle quản lý giúp cải thiện tính nhất quán, hiệu suất và độ tin cậy cho các chương trình kiểm thử đo lường tự động. Tính năng này dành cho API cấp 27 trở lên, cho phép bạn định cấu hình các thiết bị kiểm thử thực từ xa hoặc thiết bị kiểm thử ảo trong các tệp Gradle của dự án. Hệ thống xây dựng sử dụng cấu hình để quản lý hoàn toàn, tức là tạo, triển khai và chia nhỏ các thiết bị đó khi thực thi kiểm thử tự động.

Tính năng này cấp cho Gradle quyền truy cập không chỉ vào các chương trình kiểm thử bạn đang chạy, mà còn cả vòng đời của các thiết bị, nhờ đó cải thiện chất lượng trải nghiệm kiểm thử của bạn theo các cách sau:

  • Xử lý những vấn đề liên quan đến thiết bị để đảm bảo các chương trình kiểm thử của bạn được thực thi
  • Đối với thiết bị ảo, sử dụng ảnh chụp nhanh trình mô phỏng để cải thiện thời gian khởi động thiết bị và mức sử dụng bộ nhớ, đồng thời khôi phục thiết bị về trạng thái sạch giữa các lần kiểm thử
  • Lưu các kết quả kiểm thử vào bộ nhớ đệm và chỉ chạy lại các chương trình kiểm thử có khả năng cung cấp kết quả khác
  • Cung cấp một môi trường nhất quán để chạy các chương trình kiểm thử giữa các lần chạy chương trình kiểm thử cục bộ và từ xa

Tạo thiết bị ảo do Gradle quản lý

Bạn có thể chỉ định một thiết bị ảo mà bạn muốn Gradle dùng để kiểm thử ứng dụng của mình trong tệp bản dựng cấp mô-đun. Mã mẫu sau đây sẽ tạo một Pixel 2 chạy API cấp 30 dưới dạng một thiết bị do Gradle quản lý.

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

Groovy

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // Use only API levels 27 and higher.
          apiLevel = 30
          // To include Google services, use "google".
          systemImageSource = "aosp"
        }
      }
    }
  }
}

Xác định nhóm thiết bị

Để giúp bạn mở rộng quy mô kiểm thử trên nhiều cấu hình thiết bị, chẳng hạn như các cấp độ API và hệ số hình dạng khác nhau, bạn có thể xác định nhiều thiết bị do Gradle quản lý và thêm các thiết bị đó vào một nhóm được đặt tên. Sau đó, Gradle có thể thực thi song song các chương trình kiểm thử của bạn trên tất cả các thiết bị trong nhóm.

Ví dụ bên dưới cho thấy 2 thiết bị được thêm vào một nhóm thiết bị có tên là phoneAndTablet.

Kotlin

testOptions {
  managedDevices {
    localDevices {
      create("pixel2api29") { ... }
      create("nexus9api30") { ... }
    }
    groups {
      create("phoneAndTablet") {
        targetDevices.add(devices["pixel2api29"])
        targetDevices.add(devices["nexus9api30"])
      }
    }
  }
}

Groovy

testOptions {
  managedDevices {
    localDevices {
      pixel2api29 { ... }
      nexus9api30 { ... }
    }
    groups {
      phoneAndTablet {
        targetDevices.add(devices.pixel2api29)
        targetDevices.add(devices.nexus9api30)
      }
    }
  }
}

Chạy chương trình kiểm thử

Để chạy chương trình kiểm thử bằng các thiết bị do Gradle quản lý mà bạn đã định cấu hình, hãy dùng lệnh sau. device-name là tên của thiết bị mà bạn đã định cấu hình trong tập lệnh bản dựng Gradle (chẳng hạn như pixel2api30) và BuildVariant là biến thể bản dựng của ứng dụng mà bạn muốn kiểm thử.

Trên Windows:

gradlew device-nameBuildVariantAndroidTest

Trên Linux hoặc macOS:

./gradlew device-nameBuildVariantAndroidTest

Để chạy chương trình kiểm thử trên một nhóm thiết bị do Gradle quản lý, hãy dùng các lệnh sau.

Trên Windows:

gradlew group-nameGroupBuildVariantAndroidTest

Trên Linux hoặc macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

Kết quả kiểm thử bao gồm một đường dẫn đến tệp HTML có báo cáo kiểm thử. Bạn cũng có thể nhập kết quả kiểm thử vào Android Studio để phân tích thêm bằng cách nhấp vào Run > Test History (Chạy > Nhật ký kiểm thử) trong IDE.

Bật tính năng phân đoạn kiểm thử

Thiết bị do Gradle quản lý hỗ trợ tính năng phân đoạn kiểm thử, cho phép bạn phân tách bộ kiểm thử trên một số thực thể thiết bị ảo giống nhau, được gọi là phân đoạn (chạy song song). Việc sử dụng tính năng phân đoạn kiểm thử có thể giúp giảm tổng thời gian chạy chương trình kiểm thử nhưng sẽ cần tài nguyên điện toán bổ sung.

Để đặt số lượng phân đoạn bạn muốn sử dụng trong một lần chạy chương trình kiểm thử nhất định, hãy đặt nội dung sau trong tệp gradle.properties:

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

Khi chạy chương trình kiểm thử bằng tuỳ chọn này, thiết bị do Gradle quản lý cung cấp số lượng phân đoạn mà bạn chỉ định cho mỗi hồ sơ thiết bị trong lần chạy chương trình kiểm thử. Ví dụ: nếu bạn triển khai kiểm thử cho một nhóm thiết bị gồm 3 thiết bị và đặt numManagedDeviceShards thành 2, thì thiết bị do Gradle quản lý sẽ cung cấp tổng cộng 6 thiết bị ảo cho lần chạy chương trình kiểm thử đó.

Khi chương trình kiểm thử hoàn tất, Gradle sẽ xuất ra kết quả kiểm thử trong một tệp .proto cho từng phân đoạn được dùng trong lần chạy chương trình kiểm thử.

Sử dụng thiết bị kiểm thử tự động

Thiết bị do Gradle quản lý hỗ trợ một loại thiết bị trình mô phỏng tên là Thiết bị kiểm thử tự động (ATD). Công cụ này được tối ưu hoá để giảm tài nguyên CPU và bộ nhớ khi chạy chương trình kiểm thử đo lường. ATD cải thiện hiệu suất thời gian chạy theo một số cách:

  • Xoá các ứng dụng cài đặt sẵn thường không hữu ích khi bạn kiểm thử ứng dụng
  • Tắt một số dịch vụ nền thường không hữu ích cho việc kiểm thử ứng dụng
  • Tắt tính năng kết xuất phần cứng

Trước khi bắt đầu, hãy nhớ cập nhật Trình mô phỏng Android lên phiên bản mới nhất. Sau đó, hãy chỉ định hình ảnh "-atd" khi xác định một thiết bị do Gradle quản lý trong tệp bản dựng cấp mô-đun, như minh hoạ dưới đây:

Kotlin

android {
  testOptions {
    managedDevices {
      localDevices {
        create("pixel2api30") {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

Groovy

android {
  testOptions {
    managedDevices {
      localDevices {
        pixel2api30 {
          // Use device profiles you typically see in Android Studio.
          device = "Pixel 2"
          // ATDs currently support only API level 30.
          apiLevel = 30
          // You can also specify "google-atd" if you require Google Play Services.
          systemImageSource = "aosp-atd"
        }
      }
    }
  }
}

Bạn cũng có thể tạo nhóm thiết bị tương tự như với các thiết bị khác do Gradle quản lý. Để tận dụng thêm các cải tiến về hiệu suất, bạn cũng có thể sử dụng ATD với tính năng phân đoạn kiểm thử để giảm tổng thời gian thực thi kiểm thử của bộ kiểm thử.

Những thành phần nào bị xoá khỏi hình ảnh ATD?

Ngoài việc hoạt động ở chế độ không có giao diện người dùng, ATD còn tối ưu hoá hiệu suất bằng cách xoá hoặc vô hiệu hoá các ứng dụng và dịch vụ thường không cần thiết để kiểm thử mã ứng dụng. Bảng dưới đây cung cấp thông tin tổng quan về các thành phần mà chúng tôi đã xoá hoặc vô hiệu hoá trong hình ảnh ATD và mô tả lý do các thành phần này có thể không hữu ích.

Những thành phần bị xoá khỏi hình ảnh ATD Lý do bạn có thể không cần những thành phần này khi chạy chương trình kiểm thử tự động
Ứng dụng sản phẩm của Google:
  • Thư
  • Maps
  • Chrome
  • Tin nhắn
  • Cửa hàng Play và các cửa hàng khác
Các bài kiểm thử tự động của bạn nên tập trung vào logic của ứng dụng trong khi giả định rằng các ứng dụng khác hoặc nền tảng này sẽ hoạt động đúng cách.

Với Espresso-Intents, bạn có thể so khớp và xác thực các ý định gửi đi hoặc thậm chí là cung cấp các phản hồi giả lập thay cho các phản hồi thực tế về ý định.

Cài đặt ứng dụng và dịch vụ:
  • CarrierConfig
  • EmergencyInfo
  • OneTimeInitializer
  • PhotoTable (trình bảo vệ màn hình)
  • Cấp phép
  • Ứng dụng Cài đặt
  • StorageManager
  • Cấu hình APN điện thoại
  • WallpaperCropper
  • WallpaperPicker
Những ứng dụng như vậy hiển thị một GUI (Giao diện người dùng đồ hoạ) để người dùng cuối thay đổi chế độ cài đặt nền tảng, thiết lập thiết bị hoặc quản lý bộ nhớ của thiết bị. Điều này thường nằm ngoài phạm vi của kiểm thử tự động cấp ứng dụng.


Lưu ý: Nhà cung cấp chế độ cài đặt vẫn có trong hình ảnh ATD.

SystemUI Các bài kiểm thử tự động của bạn nên tập trung vào logic của ứng dụng trong khi giả định rằng các ứng dụng khác hoặc nền tảng này sẽ hoạt động đúng cách.
Ứng dụng và dịch vụ AOSP:
  • Browser2
  • Lịch
  • Camera2
  • Danh bạ
  • Trình quay số
  • DeskClock
  • Gallery2
  • LatinIME
  • Launcher3QuickStep
  • Âm nhạc
  • QuickSearchBox
  • SettingsIntelligence
Những ứng dụng và dịch vụ này thường nằm ngoài phạm vi kiểm thử tự động cho mã của ứng dụng.

Sử dụng các thiết bị trong Phòng thử nghiệm Firebase

Bạn có thể chạy chương trình kiểm thử đo lường tự động trên quy mô lớn trên các thiết bị trong Phòng thử nghiệm Firebase khi sử dụng các thiết bị do Gradle quản lý. Phòng thử nghiệm cho phép bạn chạy đồng thời các chương trình kiểm thử trên nhiều thiết bị Android, cả thiết bị thực và ảo. Các chương trình kiểm thử này chạy trong các trung tâm dữ liệu từ xa của Google. Với sự hỗ trợ của các thiết bị do Gradle quản lý, hệ thống xây dựng có thể quản lý toàn bộ các hoạt động kiểm thử đang chạy đối với các thiết bị trong Phòng thử nghiệm này dựa trên cấu hình của bạn.

Bắt đầu

Các bước sau đây mô tả cách bắt đầu sử dụng các thiết bị trong Phòng thử nghiệm Firebase với thiết bị do Gradle quản lý. Xin lưu ý rằng các bước này sử dụng Giao diện dòng lệnh (CLI) của gcloud để cung cấp thông tin đăng nhập của người dùng. Thông tin đăng nhập này có thể không sử dụng được trong một số môi trường phát triển. Để biết thêm thông tin về quy trình xác thực cần sử dụng cho nhu cầu của bạn, hãy xem phần Cách hoạt động của Thông tin xác thực mặc định của ứng dụng.

  1. Để tạo một dự án Firebase, hãy chuyển đến bảng điều khiển của Firebase. Nhấp vàoAdd project (Thêm dự án) rồi làm theo lời nhắc trên màn hình để tạo một dự án. Ghi nhớ mã dự án của bạn.

  2. Để cài đặt Google Cloud CLI, hãy làm theo các bước trong phần Cài đặt gcloud CLI.

  3. Định cấu hình môi trường cục bộ.

    1. Liên kết đến dự án Firebase của bạn trong gcloud:

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. Cho phép sử dụng thông tin đăng nhập của người dùng để có quyền truy cập API. Bạn nên cấp quyền bằng cách truyền tệp JSON của tài khoản dịch vụ cho Gradle bằng cách sử dụng DSL trong tập lệnh bản dựng cấp mô-đun:

      Kotlin

      firebaseTestLab {
        ...
        serviceAccountCredentials.set(file(SERVICE_ACCOUNT_JSON_FILE))
      }
      

      Groovy

      firebaseTestLab {
        ...
        serviceAccountCredentials = file(SERVICE_ACCOUNT_JSON_FILE)
      }
      

      Ngoài ra, bạn có thể uỷ quyền thủ công bằng cách dùng lệnh trong cửa sổ dòng lệnh sau đây:

      gcloud auth application-default login
      
    3. Không bắt buộc: Thêm dự án Firebase ở dạng dự án hạn mức. Bước này chỉ cần thiết nếu bạn vượt quá hạn mức không mất phí của Phòng thử nghiệm.

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
  4. Bật các API bắt buộc.

    Trên trang Thư viện API Google Developers Console, hãy bật Cloud Testing APICloud Tool Results API bằng cách nhập các tên API này vào hộp tìm kiếm ở đầu bảng điều khiển rồi nhấp vào Enable API (Bật API) trên trang tổng quan của từng API.

  5. Định cấu hình dự án Android của bạn.

    1. Thêm trình bổ trợ Phòng thử nghiệm Firebase vào tập lệnh bản dựng cấp cao nhất:

      Kotlin

      plugins {
        ...
        id("com.google.firebase.testlab") version "0.0.1-alpha05" apply false
      }
      

      Groovy

      plugins {
        ...
        id 'com.google.firebase.testlab' version '0.0.1-alpha05' apply false
      }
      
    2. Bật các loại thiết bị tuỳ chỉnh trong tệp gradle.properties:

      android.experimental.testOptions.managedDevices.customDevice=true
      
    3. Thêm trình bổ trợ Phòng thử nghiệm Firebase vào tập lệnh bản dựng cấp mô-đun:

      Kotlin

      plugins {
       ...
       id "com.google.firebase.testlab"
      }
      

      Groovy

      plugins {
       ...
       id 'com.google.firebase.testlab'
      }
      

Chỉ định một thiết bị cho Phòng thử nghiệm

Bạn có thể chỉ định một thiết bị cho Phòng thử nghiệm Firebase để Gradle sử dụng cho việc kiểm thử ứng dụng của bạn trong tập lệnh bản dựng cấp mô-đun. Mã mẫu sau đây sẽ tạo một Pixel 3 chạy API cấp 30 ở dạng một thiết bị cho Phòng thử nghiệm do Gradle quản lý có tên là ftlDevice. Khối firebaseTestLab {} sẽ có sẵn khi bạn áp dụng trình bổ trợ com.google.firebase.testlab cho mô-đun của mình.

Kotlin

firebaseTestLab {
  managedDevices {
    create("ftlDevice") {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Groovy

firebaseTestLab {
  managedDevices {
    ftlDevice {
      device = "Pixel3"
      apiLevel = 30
    }
  }
  ...
}

Để xác định một nhóm các thiết bị do Gradle quản lý, bao gồm cả các thiết bị trong Phòng thử nghiệm Firebase, hãy xem phần Xác định các nhóm thiết bị.

Để chạy các chương trình kiểm thử của bạn, hãy sử dụng các lệnh tương tự dùng để chạy các thiết bị khác do Gradle quản lý. Xin lưu ý rằng Gradle không chạy các chương trình kiểm thử song song hoặc hỗ trợ các cấu hình Google Cloud CLI khác cho các thiết bị trong Phòng thử nghiệm.

Tối ưu hoá các lần chạy chương trình kiểm thử bằng tính năng phân đoạn thông minh

Hoạt động kiểm thử trên các thiết bị trong Phòng thử nghiệm do Gradle quản lý có hỗ trợ tính năng phân đoạn thông minh. Tính năng phân đoạn thông minh sẽ tự động phân phối chương trình kiểm thử của bạn trên các phân đoạn sao cho mỗi phân đoạn chạy trong khoảng thời gian gần tương tự nhau, giúp giảm công sức phân bổ thủ công và tổng thời gian chạy chương trình kiểm thử. Tính năng phân đoạn thông minh sử dụng nhật ký kiểm thử hoặc thông tin về khoảng thời gian chạy các chương trình kiểm thử trước, nhằm phân phối các chương trình kiểm thử theo cách tối ưu. Xin lưu ý rằng bạn cần có phiên bản 0.0.1-alpha05 của trình bổ trợ Gradle cho Phòng thử nghiệm Firebase để sử dụng tính năng phân đoạn thông minh.

Để bật tính năng phân đoạn thông minh, hãy chỉ định lượng thời gian diễn ra hoạt động kiểm thử trong mỗi phân đoạn. Bạn nên đặt thời lượng phân đoạn mục tiêu thành ít hơn timeoutMinutes ít nhất là 5 phút để tránh trường hợp phân đoạn bị huỷ trước khi quá trình kiểm thử có thể hoàn tất.

firebaseTestLab {
  ...
  testOptions {
    targetedShardDurationMinutes = 2
  }
}

Để tìm hiểu thêm, hãy đọc bài viết về các tuỳ chọn DSL cho thiết bị trong Phòng thử nghiệm Firebase.

Cập nhật DSL cho các thiết bị trong Phòng thử nghiệm

Bạn có thể định cấu hình thêm tuỳ chọn DSL để giúp tuỳ chỉnh quá trình chạy chương trình kiểm thử hoặc di chuyển từ các giải pháp khác mà có thể bạn đang sử dụng. Hãy xem một số tuỳ chọn trong số này như mô tả trong đoạn mã sau.

firebaseTestLab {
  ...

  /**
   * A path to a JSON file that contains service account credentials to access to
   * a Firebase Test Lab project.
   */
  serviceAccountCredentials.set(file("your_service_account_credentials.json"))


  testOptions {
    fixture {
      /**
       * Whether to grant permissions on the device before tests begin.
       * Available options are "all" or "none".
       *
       * Default value is "all".
       */
      grantedPermissions = "all"

      /**
       * Map of files to push to the device before starting the test.
       *
       * The key is the location on the device.
       * The value is the location of the file, either local or in Google Cloud.
       */
      extraDeviceFiles["/sdcard/dir1/file1.txt"] = "local/file.txt"
      extraDeviceFiles["/sdcard/dir2/file2.txt"] = "gs://bucket/file.jpg"

      /**
       * The name of the network traffic profile.
       *
       * Specifies network conditions to emulate when running tests.
       *
       * Default value is empty.
       */
      networkProfile = "LTE"
    }

    execution {
      /**
       * The maximum time to run the test execution before cancellation,
       * measured in minutes. Does not include the setup or teardown of device,
       * and is handled server-side.
       *
       * The maximum possible testing time is 45 minutes on physical devices
       * and 60 minutes on virtual devices.
       *
       * Defaults to 15 minutes.
       */
       timeoutMinutes = 30

      /**
       * Number of times the test should be rerun if tests fail.
       * The number of times a test execution should be retried if one
       * or more of its test cases fail.
       *
       * The max number of times is 10.
       *
       * The default number of times is 0.
       */
      maxTestReruns = 2

      /**
       * Ensures only a single attempt is made for each execution if
       * an infrastructure issue occurs. This doesn't affect `maxTestReruns`.
       * Normally, two or more attempts are made by Firebase Test Lab if a
       * potential infrastructure issue is detected. This is best enabled for
       * latency sensitive workloads. The number of execution failures might be
       * significantly greater with `failFast` enabled.
       *
       * Defaults to false.
       */
      failFast = false

      /**
       * The number of shards to split the tests across.
       *
       * Default to 0 for no sharding.
       */
      numUniformShards = 20
    }

    /**
     * For smart sharding, the target length of time each shard should takes in
     * minutes. Maxes out at 50 shards for physical devices and 100 shards for
     * virtual devices.
     *
     * Only one of numUniformShards or targetedShardDurationMinutes can be set.
     *
     * Defaults to 0 for no smart sharding.
     */
     targetedShardDurationMinutes = 15
    }

    results {
      /**
       * The name of the Google storage bucket to store the test results in.
       *
       * If left unspecified, the default bucket is used.
       *
       * Please refer to Firebase Test Lab permissions for required permissions
       * for using the bucket.
       */
      cloudStorageBucket = "bucketLocationName"

      /**
       * Name of test results for the Firebase console history list.
       * All tests results with the same history name are grouped
       * together in the Firebase console in a time-ordered test history list.
       *
       * Defaults to the application label in the APK manifest in Flank/Fladle.
       */
      resultsHistoryName = "application-history"

      /**
       * List of paths to copy from the test device's storage to the test
       * results folder. These must be absolute paths under /sdcard or
       * /data/local/tmp.
       */
      directoriesToPull.addAll(
        "/sdcard/path/to/something"
      )

      /**
       * Whether to enable video recording during the test.
       *
       * Disabled by default.
       */
      recordVideo = false

      /**
       * Whether to enable performance metrics. If enabled, monitors and records
       * performance metrics such as CPU, memory, and network usage.
       *
       * Defaults to false.
       */
      performanceMetrics = true
  }
}