بدء استخدام اختبارات حلقة الألعاب لأجهزة iOS

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

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

ما هو اختبار حلقة الألعاب؟

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

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

  • تشغيل لعبتك بأعلى إعدادات الجودة لمعرفة الأجهزة التي يمكنها تشغيلها.

  • إجراء اختبار فني، مثل تجميع عدة مظلّلات وتنفيذها والتحقّق من أنّ الناتج هو المتوقّع.

الخطوة 1: تسجيل نظام عناوين URL المخصّص في Test Lab

أولاً، عليك تسجيل Firebase Test Lab's مخطّط URL مخصّص في تطبيقك:

  1. في Xcode، اختَر هدف مشروع.

  2. انقر على علامة التبويب معلومات ، ثم أضِف نوع عنوان URL جديدًا.

  3. في الحقل أنظمة عناوين URL ، أدخِل firebase-game-loop. يمكنك أيضًا تسجيل مخطّط URL مخصّص عن طريق إضافته إلى ملف إعداد مشروعك Info.plist في أي مكان ضمن العلامة <dict>:

    <key>CFBundleURLTypes</key>
     <array>
         <dict>
             <key>CFBundleURLName</key>
             <string></string>
             <key>CFBundleTypeRole</key>
             <string>Editor</string>
             <key>CFBundleURLSchemes</key>
             <array>
                 <string>firebase-game-loop</string>
             </array>
         </dict>
     </array>
    

تم الآن إعداد تطبيقك لتشغيل اختبار باستخدام Test Lab.

الخطوة 2 (اختيارية): إعداد تطبيقك لتشغيل حلقات متعددة

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

في مفوّض تطبيقك، يمكنك إلغاء طريقة application(_:open:options:):

Swift

func application(_app: UIApplication,
                 open url: URL
                 options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
    if components.scheme == "firebase-game-loop" {
        // ...Enter Game Loop Test logic to override application(_:open:options:).
    }
    return true
}

Objective-C

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary &lt;UIApplicationOpenURLOptionsKey, id&gt; *)options {
  if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
      // ...Enter Game Loop Test logic to override application(_:open:options:).
  }
}

عند تشغيل حلقات متعددة في اختبارك، يتم تمرير الحلقة الحالية كمعلَمة إلى عنوان URL المستخدَم لبدء التطبيق. يمكنك أيضًا الحصول على رقم الحلقة الحالية عن طريق تحليل عنصر URLComponents المستخدَم لجلب مخطّط URL مخصّص:

Swift

if components.scheme == "firebase-game-loop" {
    // Iterate over all parameters and find the one with the key "scenario".
    let scenarioNum = Int(components.queryItems!.first(where: { $0.name == "scenario" })!.value!)!
    // ...Write logic specific to the current loop (scenarioNum).
}

Objective-C

if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
    // Launch the app as part of a game loop.
    NSURLComponents *components = [NSURLComponents componentsWithURL:url
                                             resolvingAgainstBaseURL:YES];
    for (NSURLQueryItem *item in [components queryItems]) {
        if ([item.name isEqualToString:@"scenario"]) {
            NSInteger scenarioNum = [item.value integerValue];
            // ...Write logic specific to the current loop (scenarioNum).
        }
    }
}

الخطوة 3: إنشاء اختبار وتشغيله

بعد تسجيل نظام عناوين URL المخصّص في Test Lab، يمكنك تشغيل اختبارك في Firebase وحدة التحكّم أو باستخدام واجهة سطر الأوامر gcloud beta. إذا لم يسبق لك إجراء ذلك، أنشئ ملف IPA لتطبيقك (ستحتاج إلى تحديد موقعه لاحقًا).

تشغيل اختبار في وحدة التحكّم Firebase

  1. في وحدة التحكّم Firebase، انتقِل إلى DevOps والتفاعل > مركز الاختبار الافتراضي.

  2. انقر على تشغيل اختبارك الأول > تشغيل حلقة ألعاب iOS.

  3. في قسم تحميل التطبيق ، انقر على تصفُّح ، ثم اختَر ملف IPA الخاص بتطبيقك (إذا لم يسبق لك إجراء ذلك، أنشئ ملف IPA لتطبيقك).

  4. (اختياري) إذا كنت تريد تشغيل حلقات متعددة (تُعرف أيضًا باسم السيناريوهات) في الوقت نفسه أو اختيار حلقات معيّنة لتشغيلها، أدخِل أرقام الحلقات في الحقل السيناريوهات.

    على سبيل المثال، عند إدخال 1-3, 5، يشغّل Test Lab الحلقات 1 و2 و3 و5. تلقائيًا (إذا لم تُدخِل أي شيء في الحقل السيناريوهات)، يشغّل Test Lab الحلقة 1 فقط.

  5. في قسم الأجهزة ، اختَر جهازًا فعليًا واحدًا أو أكثر تريد اختبار تطبيقك عليه، ثم انقر على بدء الاختبارات.

تشغيل اختبار باستخدام واجهة سطر الأوامر gcloud beta

  1. إذا لم يسبق لك إجراء ذلك، اضبط بيئة gcloud SDK المحلية، ثم احرص على تثبيت مكوّن gcloud beta.

  2. شغِّل الأمر gcloud beta firebase test ios run واستخدِم العلامات التالية لضبط عملية التشغيل:

علامات اختبارات حلقة الألعاب
--type

مطلوب: يحدّد نوع اختبار iOS الذي تريد تشغيله. يمكنك إدخال أنواع الاختبار xctest (تلقائي) أو game-loop.

--app

مطلوب: المسار المطلق (Google Cloud Storage أو نظام الملفات) إلى ملف IPA الخاص بتطبيقك. لا تكون هذه العلامة صالحة إلا عند تشغيل اختبارات حلقة الألعاب.

--scenario-numbers

الحلقات (تُعرف أيضًا باسم السيناريوهات) التي تريد تشغيلها في تطبيقك. يمكنك إدخال حلقة واحدة أو قائمة بالحلقات أو نطاق من الحلقات. الحلقة التلقائية هي 1.

على سبيل المثال، يشغّل الرمز --scenario-numbers=1-3,5 الحلقات 1 و2 و3 و5.

--device-model

الجهاز الفعلي الذي تريد تشغيل اختبارك عليه (تعرَّف على الأجهزة المتاحة التي يمكنك استخدامها).

--timeout

المدة القصوى التي تريد أن يستغرقها اختبارك. يمكنك إدخال عدد صحيح لـ تمثيل المدة بالثواني، أو عدد صحيح وتعداد لتمثيل الـ مدة كوحدة زمنية أطول.

على سبيل المثال:

  • --timeout=200 يفرض إنهاء اختبارك عندما يصل إلى 200 ثانية.
  • يفرض الرمز --timeout=1h إنهاء اختبارك عندما يصل إلى ساعة واحدة.

على سبيل المثال، يشغّل الأمر التالي اختبار حلقة ألعاب ينفّذ الحلقات 1 و4 و6 و7 و8 على جهاز iPhone 8 Plus:

gcloud beta firebase test ios run
 --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8
 --device-model=iphone8plus

لمزيد من المعلومات عن واجهة سطر الأوامر gcloud، يُرجى الاطّلاع على المستندات المرجعية.

تشغيل اختبار محليًا

لتشغيل اختبارك محليًا، حمِّل تطبيق الألعاب في محاكي وشغِّل ما يلي:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
  • يمكنك العثور على المعرّف الفريد للجهاز (UDID) الخاص بالمحاكي عن طريق تشغيل الأمر instruments -s devices.

  • إذا كان هناك محاكي واحد فقط قيد التشغيل، أدخِل السلسلة الخاصة "booted" بدلاً من SIMULATOR_UDID.

إذا كان اختبارك يتضمّن حلقات متعددة، يمكنك تحديد الحلقة التي تريد تشغيلها عن طريق تمرير رقم الحلقة إلى العلامة scenario. يُرجى العِلم أنّه يمكنك تشغيل حلقة واحدة فقط في كل مرة عند تشغيل اختبارك محليًا. على سبيل المثال، إذا كنت تريد تشغيل الحلقات 1 و2 و5، عليك تشغيل أمر منفصل لكل حلقة:

xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=1
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5

إنهاء اختبار مبكرًا

تلقائيًا، يستمر اختبار حلقة الألعاب في التشغيل إلى أن يصل إلى مهلة مدتها خمس دقائق، حتى عند تنفيذ جميع الحلقات. عند بلوغ المهلة، ينتهي الاختبار ويتم إلغاء أي حلقات معلّقة. يمكنك تسريع اختبارك أو إنهاؤه مبكرًا عن طريق استدعاء نظام عناوين URL المخصّص في Test Lab firebase-game-loop-complete في AppDelegate الخاص بتطبيقك. على سبيل المثال:

Swift

/// End the loop by calling our custom url scheme.
func finishLoop() {
    let url = URL(string: "firebase-game-loop-complete://")!
    UIApplication.shared.open(url)
}

Objective-C

- (void)finishLoop {
  UIApplication *app = [UIApplication sharedApplication];
  [app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
      options:@{}
completionHandler:^(BOOL success) {}];
}

ينهي اختبار حلقة الألعاب الحلقة الحالية وينفّذ الحلقة التالية. وعند عدم توفّر حلقات أخرى لتشغيلها، ينتهي الاختبار.

كتابة نتائج اختبار مخصّصة

يمكنك إعداد اختبار حلقة الألعاب لكتابة نتائج اختبار مخصّصة في نظام ملفات جهازك. وبهذه الطريقة، عندما يبدأ الاختبار في التشغيل، Test Lab يخزّن ملفات النتائج في دليل GameLoopsResults على جهاز الاختبار (عليك إنشاء هذا الدليل بنفسك). عند انتهاء الاختبار، ينقل Test Labجميع الملفات من دليل GameLoopResultsإلى مجموعة مشروعك. يُرجى مراعاة ما يلي عند إعداد اختبارك:

  • يتم تحميل جميع ملفات النتائج بغض النظر عن نوع الملف أو حجمه أو عدده.

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

لإعداد اختبارك لكتابة نتائج اختبار مخصّصة:

  1. في دليل Documents الخاص بتطبيقك، أنشئ دليلاً باسم GameLoopResults.

  2. من أي مكان في رمز تطبيقك (مثل مفوّض تطبيقك)، أضِف ما يلي:

    Swift

    /// Write to a results file.
    func writeResults() {
      let text = "Greetings from game loops!"
      let fileName = "results.txt"
      let fileManager = FileManager.default
      do {
    
      let docs = try fileManager.url(for: .documentDirectory,
                                     in: .userDomainMask,
                                     appropriateFor: nil,
                                     create: true)
      let resultsDir = docs.appendingPathComponent("GameLoopResults")
      try fileManager.createDirectory(
          at: resultsDir,
          withIntermediateDirectories: true,
          attributes: nil)
      let fileURL = resultsDir.appendingPathComponent(fileName)
      try text.write(to: fileURL, atomically: false, encoding: .utf8)
      } catch {
        // ...Handle error writing to file.
      }
    }
    

    Objective-C

    /// Write to a results file.
    - (void)writeResults:(NSString *)message {
        // Locate and create the results directory (if it doesn't exist already).
        NSFileManager *manager = [NSFileManager defaultManager];
        NSURL* url = [[manager URLsForDirectory:NSDocumentDirectory
                                      inDomains:NSUserDomainMask] lastObject];
        NSURL* resultsDir = [url URLByAppendingPathComponent:@"GameLoopResults"
                                                 isDirectory:YES];
        [manager createDirectoryAtURL:resultsDir
          withIntermediateDirectories:NO
                           attributes:nil
                                error:nil];
    
        // Write the result message to a text file.
        NSURL* resultFile = [resultsDir URLByAppendingPathComponent:@"result.txt"];
        if ([manager fileExistsAtPath:[resultFile path]]) {
            // Append to the existing file
            NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:resultFile
                                                                     error:nil];
            [handle seekToEndOfFile];
            [handle writeData:[message dataUsingEncoding:NSUTF8StringEncoding]];
            [handle closeFile];
        } else {
            // Create and write to the file.
            [message writeToURL:resultFile
                     atomically:NO
                       encoding:NSUTF8StringEncoding error:nil];
        }
    }