获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

ابدأ باختبارات Game Loop

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

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

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

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

قبل ان تبدأ

لتنفيذ اختبار ، يجب عليك أولاً تهيئة تطبيقك لاختبارات Game Loop.

  1. في بيان التطبيق الخاص بك ، أضف عامل تصفية جديد للهدف إلى نشاطك :

    <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 ) ، أضف ما يلي:

    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
    }

    Kotlin+KTX

    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
    }

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

  3. موصى به: في نهاية الاختبار ، أضف:

    Java

    yourActivity.finish();

    Kotlin+KTX

    yourActivity.finish()

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

قم بإنشاء وتشغيل اختبار Game Loop

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

تشغيل على جهاز محلي

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

لإجراء اختبار على جهاز محلي باستخدام مدير حلقة الاختبار:

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

تشغيل في معمل الاختبار

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

استخدم وحدة تحكم Firebase

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

لمزيد من المعلومات حول بدء استخدام وحدة تحكم Firebase ، راجع بدء الاختبار باستخدام وحدة تحكم Firebase.

استخدم سطر أوامر gcloud (CLI)

  1. إذا لم تكن قد قمت بذلك بالفعل ، فقم بتنزيل وتثبيت Google Cloud SDK.

  2. قم بتسجيل الدخول إلى gcloud CLI باستخدام حساب 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
    

لمزيد من المعلومات حول بدء استخدام gcloud CLI ، راجع بدء الاختبار من سطر أوامر gcloud.

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

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

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

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

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

Java

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

Kotlin+KTX

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

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

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);

Kotlin+KTX

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);

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. يمكن أن تحتوي المناطق المعروضة كـ /.../ على أي حقول مخصصة تحتاجها ، طالما أنها لا تتعارض مع أسماء الحقول الأخرى المستخدمة في هذا الملف:

{
  "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 ، يمكنك مباشرة تشغيل حلقة اللعبة هذه لإعادة إنتاج التعطل واختبار إصلاحات الأخطاء.

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

  • إذا كنت تجري اختبارًا مع مدير حلقة الاختبار:

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

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

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

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

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

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

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

    Java

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

    Kotlin+KTX

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

    يمكنك الآن تغيير سلوك الحلقة الخاصة بك بناءً على قيمة int الناتجة.

حلقات لعبة التسمية

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

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

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

  • إذا كنت تجري اختبارًا مع مدير حلقة الاختبار:

    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. في تطبيق Test Loop Manager ، أدخل تصنيفًا واحدًا أو أكثر في حقل الملصقات .

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

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

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

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

مشاكل معروفة

تتضمن اختبارات Game Loop في Test Lab المشكلات المعروفة التالية:

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