تطوير الاختبارات باستخدام الأجهزة التي تديرها Gradle

تعمل الأجهزة التي تديرها Gradle على تحسين الاتساق والأداء والموثوقية اختبارات الآلات الآلية. تتوفر هذه الميزة للمستويات 27 من واجهة برمجة التطبيقات الأعلى، تتيح لك تهيئة أجهزة الاختبار الفيزيائي الافتراضية أو عن بُعد في لملفات Gradle الخاصة بالمشروع. يستخدم نظام التصميم الإعدادات لإجراء إدارة هذه الأجهزة — أي إنشاء تلك الأجهزة ونشرها وتفكيكها عند تنفيذ اختبارات تلقائية.

ولا تتيح هذه الميزة لنظام Gradle الاطّلاع على الاختبارات التي تجريها فحسب، وكذلك دورة حياة الأجهزة، وبالتالي تحسين جودة تجربة الاختبار بالطرق التالية:

  • تتم معالجة المشاكل المتعلّقة بالأجهزة لضمان تنفيذ اختباراتك.
  • استخدام لقطات المحاكي لتحسين وقت بدء تشغيل الجهاز بالنسبة إلى الأجهزة الافتراضية واستخدام الذاكرة واستعادة حالة الأجهزة بين الاختبارات.
  • تخزن ذاكرات التخزين المؤقت نتائج الاختبار وتُعيد تشغيل الاختبارات التي يُحتمل أن تقدم نتائج مختلفة نتيجة
  • توفر بيئة متسقة لإجراء الاختبارات بين الشركات المحلية إجراء اختبارات عن بُعد

إنشاء جهاز افتراضي مُدار من خلال Gradle

يمكنك تحديد جهاز افتراضي تريد أن تستخدمه Gradle لاختبار تطبيق معين في ملف التصميم على مستوى الوحدة. يؤدي نموذج الرمز البرمجي التالي إلى إنشاء هاتف Pixel 2. تشغيل المستوى 30 لواجهة برمجة التطبيقات كجهاز مُدار من خلال Gradle.

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"
        }
      }
    }
  }
}

تحديد مجموعات الأجهزة

لمساعدتك في توسيع نطاق اختباراتك عبر تهيئات متعددة للأجهزة، مثل لمستويات واجهة برمجة تطبيقات وأشكال مختلفة، يمكنك تحديد عدة واجهات برمجة تطبيقات مُدارة من خلال نظام Gradle الأجهزة وإضافتها إلى مجموعة مُسماة. يمكن لنظام Gradle تنفيذ الاختبارات عبر جميع الأجهزة في المجموعة بالتوازي.

يوضح المثال أدناه جهازين تمت إضافتهما إلى مجموعة أجهزة تسمى 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)
      }
    }
  }
}

إجراء الاختبارات

لإجراء اختباراتك باستخدام الأجهزة المُدارة من خلال Gradle والتي ضبطتها، يمكنك استخدام الأمر التالي. يشير "device-name" إلى اسم الجهاز الذي تم ضبط إعداداته من خلاله. النص البرمجي لإنشاء Gradle (مثل pixel2api30)، وBuildVariant هو إصدار مختلف من تطبيقك تريد اختباره.

في نظام التشغيل Windows:

gradlew device-nameBuildVariantAndroidTest

على نظام التشغيل Linux أو macOS:

./gradlew device-nameBuildVariantAndroidTest

لإجراء اختباراتك على مجموعة من الأجهزة المُدارة من خلال Gradle، استخدم الأوامر التالية.

في نظام التشغيل Windows:

gradlew group-nameGroupBuildVariantAndroidTest

على نظام التشغيل Linux أو macOS:

./gradlew group-nameGroupBuildVariantAndroidTest

يتضمن ناتج الاختبار مسارًا إلى ملف HTML يحتوي على تقرير الاختبار. إِنْتَ استيراد نتائج الاختبار إلى "استوديو Android" لمزيد من التحليل من خلال النقر على تشغيل > سجلّ الاختبارات في بيئة التطوير المتكاملة

تفعيل تقسيم الاختبار إلى أجزاء

تتوافق الأجهزة المُدارة من خلال نظام Gradle مع ميزة التقسيم التجريبي، ما يتيح لك تقسيم الاختبار. في عدد من مثيلات الأجهزة الافتراضية المتماثلة، تُسمى الأجزاء، التي تعمل بالتوازي. يمكن أن يساعد استخدام التقسيم الاختباري في تقليل تنفيذ الاختبار بشكل عام على حساب الموارد الحاسوبية الإضافية.

لضبط عدد الأجزاء التي تريد استخدامها في عملية اختبار معيّنة، اضبط التالية في ملف gradle.properties:

android.experimental.androidTest.numManagedDeviceShards=<number_of_shards>

عند إجراء اختباراتك باستخدام هذا الخيار، توفر الأجهزة التي تديرها Gradle عدد الأجزاء التي تحدِّدها لكلّ ملف شخصي للجهاز أثناء إجراء الاختبار. لذلك، بالنسبة مثلاً، إذا نشرت اختباراتك على مجموعة أجهزة مكونة من ثلاثة أجهزة وضبطت من numManagedDeviceShards إلى اثنين، ستوفّر الأجهزة المُدارة من خلال Gradle إجمالي ستة أجهزة افتراضية لإجراء الاختبار.

عند اكتمال الاختبارات، تعطي Gradle نتائج الاختبار في ملف .proto. لكل جزء مستخدم في عملية الاختبار.

استخدام أجهزة اختبار مبرمَجة

تتوافق الأجهزة المُدارة من خلال نظام Gradle مع نوع من أجهزة المحاكاة يسمى جهاز اختباري (ATD)، وهو محسَّن لتقليل وحدة المعالجة المركزية (CPU) وموارد الذاكرة في حال إجراء اختبارات الأجهزة. تحسّن ATD أداء وقت التشغيل بعدة طرق:

  • إزالة التطبيقات المثبتة مسبقًا والتي لا تكون مفيدة في العادة لاختبار تطبيقك
  • إيقاف بعض الخدمات التي تعمل في الخلفية والتي تكون عادةً غير مفيدة اختبار تطبيقك
  • إيقاف عرض الأجهزة

قبل البدء، تأكد من تحديث "محاكي Android" إلى آخر إصدار والإصدار المتوفر. ثم حدد "-atd" صورة عند تحديد واجهة برمجة تطبيقات تديرها Gradle الجهاز في ملف التصميم على مستوى الوحدة، كما هو موضح أدناه:

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"
        }
      }
    }
  }
}

يمكنك أيضًا إنشاء مجموعات أجهزة كما تفعل مع الأجهزة المُدارة من خلال Gradle للاستفادة بشكل أكبر من تحسينات الأداء، عليك كما يمكن استخدام ATD مع تقسيم الاختبار لخفض إجمالي الاختبار ووقت تنفيذ مجموعة الاختبار.

ما هي العناصر التي تتم إزالتها من صور ATD؟

وبالإضافة إلى العمل في وضع التشغيل بلا واجهة مستخدم رسومية، تعمل ATD أيضًا على تحسين الأداء من خلال إزالة أو إيقاف التطبيقات والخدمات غير المطلوبة عادةً اختبار رمز التطبيق. يعرض الجدول أدناه نظرة عامة على المكوّنات أزلناها أو أوقفناها في صور ATD وأوصاف الأسباب التي قد تؤدي إلى عدم أن تكون مفيدة.

العناصر التي تتم إزالتها في صور ATD أسباب عدم استخدام هذه الميزة عند إجراء اختبارات مبرمَجة
تطبيقات منتجات Google:
  • البريد
  • Maps
  • Chrome
  • الرسائل
  • "متجر Play" وغير ذلك
وينبغي أن تركز اختباراتك الآلية على منطق تطبيقك مع افتراض أن أن تعمل التطبيقات الأخرى أو النظام الأساسي بشكل صحيح.

باستخدام Espresso-Intents يمكنك مطابقة رغباتك الصادرة والتحقّق منها أو حتى تقديم بدائل ردودًا بدلاً من ردود النية الفعلية.

إعدادات التطبيقات والخدمات:
  • إعداد مشغِّل شبكة الجوّال
  • معلومات الطوارئ
  • تهيئة OneTime
  • PhotoTable (شاشات الاستراحة)
  • التمويل
  • تطبيق "الإعدادات"
  • أداة إدارة مساحة التخزين
  • إعدادات اسم نقطة الوصول (APN) للاتصال الهاتفي
  • أداة اقتصاص ورق الحائط
  • منتقي الخلفيات
تقدم هذه التطبيقات واجهة مستخدم تصويرية للمستخدمين النهائيين لتغيير النظام الأساسي الإعدادات أو إعداد أجهزتهم أو إدارة مساحة التخزين في الجهاز. عادةً ما تكون هذه خارج نطاق الاختبار المُبرمَج على مستوى التطبيق


ملاحظة: موفِّر الإعدادات لا يزال متاحًا في صورة ATD.

SystemUI وينبغي أن تركز اختباراتك الآلية على منطق تطبيقك مع افتراض أن أن تعمل التطبيقات الأخرى أو النظام الأساسي بشكل صحيح.
تطبيقات وخدمات AOSP:
  • المتصفح 2
  • التقويم
  • Camera2
  • جهات اتصال Google
  • Dialer
  • ساعة مكتب
  • المعرض 2
  • محرر أسلوب الإدخال اللاتيني
  • مشغّل التطبيقات3QuickStep
  • موسيقى
  • مربّع البحث السريع
  • استخبارات الإعدادات
وعادةً ما تكون هذه التطبيقات والخدمات خارج نطاق أنظمة التشغيل المبرمَجة. اختبارات التعليمات البرمجية لتطبيقك.

استخدام أجهزة مركز الاختبار الافتراضي لمنصة Firebase

يمكنك إجراء اختبارات قياس حالة التطبيق على نطاق واسع من خلال اختبار Firebase. الأجهزة الاختبارية عند استخدام الأجهزة المُدارة من خلال Gradle يتيح لك مركز الاختبار الافتراضي إجراء الاختبارات في الوقت نفسه على مجموعة واسعة من أجهزة Android، المادية والافتراضية. يتم إجراء هذه الاختبارات في مراكز بيانات Google عن بُعد. وبدعم من الأجهزة التي تديرها Gradle، فإن إصدار إدارة جميع الاختبارات الجارية على أجهزة Test Lab هذه بناءً على إعداداتك.

البدء

توضِّح الخطوات التالية كيفية بدء استخدام أجهزة مركز الاختبار الافتراضي لمنصة Firebase مع الأجهزة المُدارة من خلال Gradle يُرجى العلم أنّ هذه الخطوات تستخدم gcloud CLI لتوفير واجهة التي قد لا تنطبق على جميع بيئات التطوير. لمزيد من المعلومات، للحصول على معلومات عن عملية المصادقة التي يجب استخدامها لتلبية احتياجاتك، راجِع كيفية استخدام بيانات الاعتماد التلقائية للتطبيق .

  1. لإنشاء مشروع على Firebase، انتقِل إلى صفحة وحدة تحكُّم Firebase: (يُرجى النقر.) أضِف مشروعًا واتّبِع التعليمات التي تظهر على الشاشة لإنشاء مشروع. تذكّر رقم تعريف مشروعك.

  2. لتثبيت واجهة سطر الأوامر في Google Cloud، اتبع الخطوات الواردة في تثبيت gcloud CLI

  3. اضبط بيئتك المحلية.

    1. الربط بمشروع Firebase في gcloud:

      gcloud config set project FIREBASE_PROJECT_ID
      
    2. السماح باستخدام بيانات اعتماد المستخدم للوصول إلى واجهة برمجة التطبيقات. ننصحك بما يلي: عن طريق تمرير ملف JSON لحساب الخدمة إلى Gradle باستخدام DSL في النص البرمجي للإصدار على مستوى الوحدة:

      Kotlin

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

      Groovy

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

      بدلاً من ذلك، يمكنك التفويض يدويًا باستخدام الوحدة الطرفية التالية :

      gcloud auth application-default login
      
    3. اختياري: أضِف مشروع Firebase كمشروع الحصة. هذه الخطوة مطلوبة فقط إذا تجاوزت الحصول على حصة بدون تكلفة لبرنامج Test Lab

      gcloud auth application-default set-quota-project FIREBASE_PROJECT_ID
      
  4. تفعيل واجهات برمجة التطبيقات المطلوبة

    في جلسة المعمل، صفحة مكتبة واجهة برمجة التطبيقات Google Developers Console، تفعيل Cloud Testing API وCloud Tool Results API من خلال كتابة أسماء واجهات برمجة التطبيقات هذه في مربّع البحث أعلى وحدة التحكّم، ثم النقر على تفعيل واجهة برمجة التطبيقات في صفحة النظرة العامة لكل واجهة برمجة تطبيقات.

  5. اضبط مشروع Android.

    1. أضِف المكوّن الإضافي لمنصة Firebase Test Lab إلى النص البرمجي للإنشاء ذي المستوى الأعلى.

      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. تفعيل أنواع الأجهزة المخصّصة في ملف gradle.properties:

      android.experimental.testOptions.managedDevices.customDevice=true
      
    3. أضِف المكوّن الإضافي Firebase Test Lab إلى النص البرمجي للإصدار على مستوى الوحدة:

      Kotlin

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

      Groovy

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

تحديد جهاز Test Lab

يمكنك تحديد جهاز Firebase Test Lab لكي تستخدمه Gradle في اختبار التطبيق في نص الإنشاء على مستوى الوحدة. ينشئ نموذج التعليمات البرمجية التالي هاتف Pixel 3 يعمل بالمستوى 30 من واجهة برمجة التطبيقات كجهاز اختبار مُدار من خلال Gradle يُعرف باسم ftlDevice تتوفر المجموعة firebaseTestLab {} عند تطبيق com.google.firebase.testlab المكوّن الإضافي إلى الوحدة.

Kotlin

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

Groovy

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

لتحديد مجموعة من الأجهزة المُدارة من خلال نظام Gradle، بما في ذلك أجهزة مركز الاختبار الافتراضي لمنصة Firebase، راجِع تحديد مجموعات الأجهزة.

لإجراء اختباراتك، استخدِم الأوامر نفسها المُستخدَمة في تنفيذ اختبارات أخرى مُدارة من خلال Gradle الأجهزة. لاحظ أن Gradle لا تجري الاختبارات بالتوازي أو الدعم إعدادات سطر الأوامر الأخرى في Google Cloud لأجهزة Test Lab.

تحسين عمليات إجراء الاختبارات باستخدام التقسيم الذكي

يتوافق الاختبار على أجهزة Test Lab التي تديرها Gradle مع التقسيم الذكي. ذكي يوزّع التقسيم تلقائيًا اختباراتك على الأجزاء بحيث يصبح كل جزء منها في الوقت نفسه تقريبًا، مما يقلل من جهود التخصيص اليدوي والمدة الإجمالية لتشغيل الاختبار. تستخدم عملية التقسيم الذكي لسجلّ الاختبار أو المعلومات بشأن المدة التي استغرقتها الاختبارات في السابق لتوزيع الاختبارات في الطريقة المثلى. لاحظ أنك تحتاج إلى الإصدار 0.0.1-alpha05 من المكوّن الإضافي Gradle لمنصة Firebase Test Lab لاستخدام التقسيم الذكي.

لتفعيل التقسيم الذكي، يجب تحديد مقدار الوقت اللازم للاختبارات في كل جزء. يستغرقها المشروع. ويجب ضبط المدة الزمنية للجزء المستهدف على خمسة على الأقل دقائق أقل من timeoutMinutes لتجنُّب موضع الأجزاء قبل أن تنتهي الاختبارات.

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

لمزيد من المعلومات، يمكنك الاطّلاع على خيارات DSL لجهاز Test Lab من Firebase.

تحديث DSL لأجهزة Test Lab

هناك المزيد من خيارات DSL التي يمكنك ضبطها لمساعدتك في تخصيص عمليات إجراء الاختبارات أو الانتقال من الحلول الأخرى التي قد تستخدمها بالفعل. الاطّلاع على بعض هذه الخيارات كما هو موضح في مقتطف الرمز التالي.

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
  }
}