تطوير الاختبارات باستخدام الأجهزة التي تديرها 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"
        }
      }
    }
  }
}

رائع

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

رائع

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

رائع

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

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

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


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

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

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

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

البدء

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

  1. لإنشاء مشروع في Firebase، انتقِل إلى وحدة تحكّم Firebase. انقر على إضافة مشروع واتّبِع التعليمات التي تظهر على الشاشة لإنشاء مشروع. تذكر رقم تعريف المشروع.

  2. لتثبيت Google Cloud CLI، اتّبِع الخطوات الواردة في مقالة Install the gcloud CLI (تثبيت 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))
      }
      

      رائع

      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 وواجهة برمجة تطبيقات نتائج أداة Cloud عن طريق كتابة أسماء واجهات برمجة التطبيقات هذه في مربّع البحث أعلى وحدة التحكم، ثم النقر على تفعيل واجهة برمجة التطبيقات في صفحة النظرة العامة لكل واجهة برمجة تطبيقات.

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

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

      Kotlin

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

      رائع

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

      رائع

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

رائع

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

لتحديد مجموعة من الأجهزة المُدارة من خلال Gradle بما في ذلك أجهزة Firebase Test Lab، يمكنك الاطّلاع على تحديد مجموعات الأجهزة.

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

تحسين عمليات الاختبار باستخدام ميزة "التقسيم إلى أجزاء ذكية"

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

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

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

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

تحديث 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
  }
}