بدء استخدام اختبارات Game Loop

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

اعتمادًا على محرّك الألعاب، يمكنك إجراء اختبارات باستخدام حلقة واحدة أو حلقات متعدّدة. حلقة الألعاب هي عملية تشغيل كاملة أو جزئية للاختبار على لعبة على الأجهزة الجوّالة. ويمكن استخدام حلقات الألعاب في ما يلي:

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

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

قبل البدء

لإجراء اختبار، عليك أولاً ضبط تطبيقك لاختبارات "حلقة الألعاب".

  1. في بيان تطبيقك، أضِف intent filter جديدًا إلى نشاطك:

    <activity android:name=".MyActivity">
       <intent-filter>
           <action android:name="com.google.intent.action.TEST_LOOP"/>
           <category android:name="android.intent.category.DEFAULT"/>
           <data android:mimeType="application/javascript"/>
       </intent-filter>
       <intent-filter>
          ... (other intent filters here)
       </intent-filter>
    </activity>

    يسمح هذا الإجراء لـ Test Lab بتشغيل لعبتك من خلال تفعيلها باستخدام هدف معيّن.

  2. في الرمز البرمجي (ننصحك بإضافته داخل تعريف طريقة onCreate)، أضِف ما يلي:

    Kotlin

    val launchIntent = intent
    if (launchIntent.action == "com.google.intent.action.TEST_LOOP") {
        val scenario = launchIntent.getIntExtra("scenario", 0)
        // Code to handle your game loop here
    }

    Java

    Intent launchIntent = getIntent();
    if(launchIntent.getAction().equals("com.google.intent.action.TEST_LOOP")) {
        int scenario = launchIntent.getIntExtra("scenario", 0);
        // Code to handle your game loop here
    }

    يسمح هذا الإجراء لنشاطك بالتحقّق من الهدف الذي يشغّله. يمكنك أيضًا إضافة هذا الرمز البرمجي لاحقًا إذا كنت تفضّل ذلك (على سبيل المثال، بعد التحميل الأولي لمحرّك الألعاب).

  3. ننصحك بما يلي: في نهاية الاختبار، أضِف ما يلي:

    Kotlin

    yourActivity.finish()

    Java

    yourActivity.finish();

    يؤدي هذا الإجراء إلى إغلاق تطبيقك عند اكتمال اختبار "حلقة الألعاب". يعتمد الاختبار على إطار واجهة مستخدم تطبيقك لبدء الحلقة التالية، ويشير إغلاق تطبيقك إلى اكتمال الاختبار.

إنشاء اختبار "حلقة الألعاب" وإجراؤه

بعد ضبط تطبيقك لاختبارات "حلقة الألعاب"، يمكنك إنشاء اختبار وتشغيله على الفور في لعبة على الأجهزة الجوّالة. يمكنك اختيار إجراء اختبار في Test Lab باستخدام إما Firebase console أو gcloud واجهة سطر الأوامر (CLI)، أو على جهاز محلي باستخدام Test Loop Manager.

الإجراء على جهاز محلي

Test Lab's Test Loop Manager في Test Lab هو تطبيق مفتوح المصدر يساعدك في دمج اختبارات "حلقة الألعاب" وإجرائها على أجهزتك المحلية. ويسمح أيضًا لفريق ضمان الجودة بإجراء حلقات الألعاب نفسها على أجهزته.

لإجراء اختبار على جهاز محلي باستخدام Test Loop Manager:

  1. نزِّل Test Loop Manager على هاتف أو جهاز لوحي وثبِّته عن طريق تشغيل ما يلي:
    adb install testloopmanager.apk
  2. على جهازك، افتح تطبيق Test Loop Apps على هاتفك أو جهازك اللوحي. يعرض التطبيق قائمة بالتطبيقات على جهازك التي يمكن تشغيلها باستخدام حلقات الألعاب. إذا لم يظهر تطبيق الألعاب هنا، تأكَّد من أنّ فلتر الأهداف يطابق الفلتر الموضّح في الخطوة الأولى من قسم قبل البدء.
  3. اختَر لعبة على الأجهزة الجوّالة، ثم اختَر عدد التكرارات التي تريد تشغيلها. ملاحظة: في هذه الخطوة، يمكنك اختيار تشغيل مجموعة فرعية من الحلقات بدلاً من حلقة واحدة فقط. لمزيد من المعلومات عن تشغيل حلقات متعدّدة في الوقت نفسه، يُرجى الاطّلاع على الميزات الاختيارية.
  4. انقر على إجراء الاختبار. يبدأ الاختبار على الفور.

الإجراء في Test Lab

يمكنك إجراء اختبار "حلقة الألعاب" في Test Lab باستخدام Firebase console أو gcloud CLI. قبل البدء، إذا لم يسبق لك ذلك، افتح Firebase console وأنشئ مشروعًا.

استخدام Firebase console

  1. في Firebase console، انقر على Test Lab من اللوحة اليمنى.
  2. انقر على إجراء الاختبار الأول (أو إجراء اختبار إذا سبق أن أجريت اختبارًا في مشروعك).
  3. اختَر حلقة الألعاب كنوع الاختبار، ثم انقر على متابعة.
  4. انقر على تصفّح، ثم انتقِل إلى ملف .apk الخاص بتطبيقك. ملاحظة: في هذه الخطوة، يمكنك اختيار تشغيل مجموعة فرعية من الحلقات بدلاً من حلقة واحدة فقط. لمزيد من المعلومات عن تشغيل حلقات متعدّدة في الوقت نفسه، يُرجى الاطّلاع على الميزات الاختيارية.
  5. انقر على متابعة.
  6. اختَر الأجهزة الفعلية التي تريد استخدامها لاختبار تطبيقك.
  7. انقر على بدء الاختبارات.

لمزيد من المعلومات عن بدء استخدام Firebase console، يُرجى الاطّلاع على بدء الاختبار باستخدام Firebase console.

استخدام واجهة سطر الأوامر (CLI) في gcloud

  1. نزِّل Google Cloud SDK وثبِّتها إذا لم يسبق لك ذلك.

  2. سجِّل الدخول إلى واجهة سطر الأوامر (CLI) في gcloud باستخدام حسابك على Google:

    gcloud auth login

  3. اضبط مشروعك على Firebase في gcloud، حيث PROJECT_ID هو رقم تعريف مشروعك على Firebase:

    gcloud config set project PROJECT_ID
    
  4. أجرِ الاختبار الأول:

    gcloud firebase test android run \
     --type=game-loop --app=<var>path-to-apk</var> \
     --device model=herolte,version=23
    

لمزيد من المعلومات عن بدء استخدام واجهة سطر الأوامر (CLI) في gcloud، يُرجى الاطّلاع على بدء الاختبار من سطر أوامر gcloud.

الميزات الاختيارية

Test Lab يقدّم عدة ميزات اختيارية تتيح لك تخصيص اختباراتك بشكلٍ أكبر، بما في ذلك إمكانية كتابة بيانات الإخراج ودعم حلقات الألعاب المتعدّدة والتصنيفات للحلقات ذات الصلة.

كتابة بيانات الإخراج

يمكن لاختبار "حلقة الألعاب" كتابة الإخراج في ملف محدّد في طريقة launchIntent.getData(). بعد إجراء الاختبار، يمكنك الوصول إلى بيانات الإخراج هذه في قسم Test Lab في Firebase console (راجِع مثال ملف إخراج اختبار "حلقة الألعاب").

Test Lab يتّبع أفضل الممارسات لمشاركة ملف بين التطبيقات الموضّحة في مشاركة ملف. في طريقة onCreate() لنشاطك، حيث يوجد هدفك، يمكنك التحقّق من ملف إخراج البيانات عن طريق تشغيل الرمز البرمجي التالي:

Kotlin

val launchIntent = intent
val logFile = launchIntent.data
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    // ...
}

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    // ...
}

إذا كنت تريد الكتابة في الملف من جانب C++ لتطبيق الألعاب، يمكنك تمرير واصف الملف بدلاً من مسار الملف:

Kotlin

val launchIntent = intent
val logFile = launchIntent.data
var fd = -1
logFile?.let {
    Log.i(TAG, "Log file ${it.encodedPath}")
    fd = try {
        contentResolver
            .openAssetFileDescriptor(logFile, "w")!!
            .parcelFileDescriptor
            .fd
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
        -1
    } catch (e: NullPointerException) {
        e.printStackTrace()
        -1
    }
}

// C++ code invoked here.
// native_function(fd);

Java

Intent launchIntent = getIntent();
Uri logFile = launchIntent.getData();
int fd = -1;
if (logFile != null) {
    Log.i(TAG, "Log file " + logFile.getEncodedPath());
    try {
        fd = getContentResolver()
                .openAssetFileDescriptor(logFile, "w")
                .getParcelFileDescriptor()
                .getFd();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fd = -1;
    } catch (NullPointerException e) {
        e.printStackTrace();
        fd = -1;
    }
}

// C++ code invoked here.
// native_function(fd);

C++‎

#include <unistd.h>
JNIEXPORT void JNICALL
Java_my_package_name_MyActivity_native_function(JNIEnv *env, jclass type, jint log_file_descriptor) {
// The file descriptor needs to be duplicated.
int my_file_descriptor = dup(log_file_descriptor);
}

مثال على ملف الإخراج

يمكنك استخدام ملفات بيانات الإخراج (المنسّقة مثل المثال أدناه) لعرض نتائج اختبار "حلقة الألعاب" في قسم Test Lab في Firebase console. يمكن أن تحتوي المناطق المعروضة على شكل /.../ على أي حقول مخصّصة تحتاج إليها، طالما أنّها لا تتعارض مع أسماء الحقول الأخرى المستخدَمة في هذا الملف:

{
  "name": "test name",
  "start_timestamp": 0, // Timestamp of the test start (in us).
                           Can be absolute or relative
  "driver_info": "...",
  "frame_stats": [
    {
      "timestamp": 1200000, // Timestamp at which this section was written
                               It contains value regarding the period
                               start_timestamp(0) -> this timestamp (1200000 us)
      "avg_frame_time": 15320, // Average time to render a frame in ns
      "nb_swap": 52, // Number of frame rendered
      "threads": [
        {
          "name": "physics",
          "Avg_time": 8030 // Average time spent in this thread per frame in us
        },
        {
          "name": "AI",
          "Avg_time": 2030 // Average time spent in this thread per frame in us
        }
      ],
      /.../ // Any custom field you want (vertices display on the screen, nb units …)
    },
    {
      // Next frame data here, same format as above
    }
  ],
  "loading_stats": [
    {
      "name": "assets_level_1",
      "total_time": 7850, // in us
      /.../
    },
    {
      "name": "victory_screen",
      "total_time": 554, // in us
      /.../
    }

  ],
  /.../, // You can add custom fields here
}

حلقات ألعاب متعدّدة

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

للسماح لتطبيقك بتشغيل حلقات متعدّدة في الوقت نفسه:

  • إذا كنت تُجري اختبارًا باستخدام Test Loop Manager:

    1. أضِف السطر التالي إلى بيان تطبيقك داخل العنصر <application>

      <meta-data
        android:name="com.google.test.loops"
        android:value="5" />

      يحتوي هدف التشغيل هذا على الحلقة المستهدَفة كمعلَمة عدد صحيح. في الحقل android:value، يمكنك تحديد عدد صحيح من 1 إلى 1024 (الحد الأقصى لعدد الحلقات المسموح به لاختبار واحد). يُرجى العِلم أنّ الحلقات تتم فهرستها بدءًا من 1 وليس 0.

    2. في تطبيق Test Loop Manager، تظهر شاشة اختيار تتيح لك تحديد الحلقات التي تريد تشغيلها. إذا اخترت حلقات متعدّدة، يتم تشغيل كل حلقة بالتسلسل بعد اكتمال الحلقة السابقة.

  • إذا كنت تُجري اختبارًا باستخدام Firebase console، أدخِل قائمة أو نطاقًا من أرقام الحلقات في الحقل السيناريوهات.

  • إذا كنت تُجري اختبارًا باستخدام واجهة سطر الأوامر (CLI) في gcloud، حدِّد قائمة بأرقام الحلقات باستخدام العلامة --scenario-numbers. على سبيل المثال، يؤدي استخدام --scenario-numbers=1,3,5 إلى تشغيل الحلقات 1 و3 و5.

  • إذا كنت تكتب رمز C++ وتريد تغيير سلوك الحلقة، مرِّر الإضافة التالية إلى رمز C++ الأصلي:

    Kotlin

    val launchIntent = intent
    val scenario = launchIntent.getIntExtra("scenario", 0)

    Java

    Intent launchIntent = getIntent();
    int scenario = launchIntent.getIntExtra("scenario", 0);

    يمكنك الآن تغيير سلوك الحلقة استنادًا إلى قيمة int الناتجة.

تصنيف حلقات الألعاب

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

  • com.google.test.loops.player_experience: للحلقات المستخدَمة لإعادة إنتاج تجربة مستخدم حقيقي أثناء لعب اللعبة. الهدف من الاختبار باستخدام هذه الحلقات هو العثور على المشاكل التي قد يواجهها مستخدم حقيقي أثناء لعب اللعبة.
  • com.google.test.loops.gpu_compatibility: للحلقات المستخدَمة لاختبار المشاكل المتعلّقة بوحدة معالجة الرسومات. الهدف من الاختبار باستخدام هذه الحلقات هو تنفيذ رمز وحدة معالجة الرسومات الذي قد لا يتم تشغيله بشكلٍ صحيح في مرحلة الإنتاج، وذلك للكشف عن المشاكل في الأجهزة وبرامج التشغيل.
  • com.google.test.loops.compatibility: للحلقات المستخدَمة لاختبار مجموعة كبيرة من مشاكل التوافق، بما في ذلك مشاكل الإدخال والإخراج ومشاكل OpenSSL.
  • com.google.test.loops.performance: للحلقات المستخدَمة لاختبار أداء الجهاز. على سبيل المثال، قد يتم تشغيل لعبة بأكثر إعدادات الرسومات تعقيدًا لمعرفة سلوك جهاز جديد.

للسماح لتطبيقك بتشغيل حلقات تحمل التصنيف نفسه:

  • إذا كنت تُجري اختبارًا باستخدام Test Loop Manager:

    1. في بيان تطبيقك، أضِف سطر البيانات الوصفية التالي واستبدِل LABEL_NAME بتصنيف من اختيارك:

      <meta-data
       android:name="com.google.test.loops.LABEL_NAME"
       android:value="1,3-5" />

      في الحقل android:value، يمكنك تحديد نطاق أو مجموعة من الأعداد الصحيحة من 1 إلى 1024 (الحد الأقصى لعدد الحلقات المسموح به لاختبار واحد) التي تمثّل الحلقات التي تريد تصنيفها. يُرجى العِلم أنّ الحلقات تتم فهرستها بدءًا من 1 وليس 0. على سبيل المثال، يؤدي استخدام android:value="1,3-5" إلى تطبيق LABEL_NAME على الحلقات 1 و3 و4 و5.

    2. في تطبيق اختبار مدير الحلقة، أدخِل تصنيفًا واحدًا أو أكثر في الحقل التصنيفات.

  • إذا كنت تُجري اختبارًا باستخدام Firebase console، أدخِل تصنيفًا واحدًا أو أكثر في الحقل التصنيفات.

  • إذا كنت تُجري اختبارًا باستخدام واجهة سطر الأوامر (CLI) في gcloud، حدِّد تصنيف سيناريو واحدًا أو أكثر باستخدام --scenario-labels (على سبيل المثال، --scenario-labels=performance,gpu).

دعم ترخيص التطبيقات

Test Lab يتوافق مع التطبيقات التي تستخدم خدمة ترخيص التطبيقات التي يقدّمها Google Play. للتحقّق من الترخيص بنجاح عند اختبار تطبيقك باستخدام Test Lab، عليك نشر تطبيقك في قناة الإنتاج في "متجر Play". لاختبار تطبيقك في قناة الإصدار الأولي أو الإصدار التجريبي باستخدام Test Lab، عليك إزالة عملية التحقّق من الترخيص قبل تحميل تطبيقك إلى Test Lab.

المشكلات المعروفة

تواجه اختبارات "حلقة الألعاب" في Test Lab المشاكل المعروفة التالية:

  • لا تتيح بعض الأعطال تتبُّع مسار التنفيذ. على سبيل المثال، قد تحظر بعض إصدارات الإنشاء إخراج عملية debuggerd باستخدام prctl(PR_SET_DUMPABLE, 0). لمزيد من المعلومات، يُرجى الاطّلاع على debuggerd.
  • لا يتوافق Test Lab حاليًا مع المستوى 19 من واجهة برمجة التطبيقات بسبب أخطاء في أذونات الملفات.