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

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

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

  • قم بتشغيل مستوى من لعبتك بنفس الطريقة التي يلعب بها المستخدم النهائي. يمكنك إما كتابة نصوص لإدخال المستخدم ، أو السماح للمستخدم بالتوقف عن العمل ، أو استبدال المستخدم بذكاء اصطناعي إذا كان ذلك منطقيًا في لعبتك (على سبيل المثال ، لنفترض أن لديك تطبيق ألعاب سيارات السباق وأن لديك بالفعل تطبيق 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 بإعلان طريقة)، إضافة ما يلي:

    جافا

    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. موصى به: في نهاية الاختبار ، أضف:

    جافا

    yourActivity.finish();

    Kotlin + KTX

    yourActivity.finish()

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

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

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

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

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

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

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

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

يمكنك تشغيل اختبار لعبة حلقة في مختبر فحص باستخدام إما وحدة Firebase أو CLI gcloud. قبل أن تبدأ، إذا لم تقم بذلك بالفعل، فتح وحدة التحكم Firebase وإنشاء المشروع.

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

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

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

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

  1. إذا كنت لم تقم بذلك بالفعل، وتحميل وتثبيت جوجل الغيمة 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
    

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

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

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

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

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

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

جافا

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 ++ من تطبيق اللعبة ، فيمكنك تمرير واصف الملف بدلاً من مسار الملف:

جافا

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

سي ++

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

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

يمكنك استخدام ملفات إخراج البيانات (منسق كما في المثال أدناه) لعبة عرض نتائج الاختبار حلقة في قسم مختبر فحص للوحدة 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، أدخل قائمة أو مجموعة من الأرقام حلقة في مجال السيناريوهات.

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

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

    جافا

    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 : للحلقات تستخدم لإنتاج تجربة المستخدم الحقيقي عندما لعب اللعبة. الهدف من الاختبار باستخدام هذه الحلقات هو العثور على المشكلات التي قد يواجهها المستخدم الحقيقي أثناء لعب اللعبة.
  • com.google.test.loops.gpu_compatibility : للحلقات تستخدم لقضايا تتعلق GPU اختبار. الهدف من الاختبار باستخدام هذه الحلقات هو تنفيذ رمز GPU الذي قد لا يعمل بشكل صحيح في الإنتاج ، لفضح المشكلات المتعلقة بالأجهزة وبرامج التشغيل.
  • com.google.test.loops.compatibility : للحلقات تستخدم لاختبار مجموعة واسعة من القضايا التوافق، بما في ذلك I / O القضايا والمسائل بينسل.
  • com.google.test.loops.performance : للحلقات استخدامها لاختبار أداء الجهاز. على سبيل المثال ، قد يتم تشغيل إحدى الألعاب في أكثر إعدادات الرسومات تعقيدًا لمعرفة كيف يتصرف الجهاز الجديد.

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

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

    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، أدخل واحدة أو أكثر من العلامات في مجال العلامات.

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

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

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

مشاكل معروفة

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

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