תחילת העבודה עם בדיקות של לולאת משחקים ל-iOS

בעזרת בדיקות של לולאות משחק, אתם יכולים לכתוב בדיקות שמותאמות למנוע המשחק שלכם ואז להריץ אותן ב-Test Lab במכשירים שתבחרו. כך לא צריך לדאוג לגבי כתיבה לממשקי משתמש שונים או למסגרות בדיקה שונות. בדיקת לולאת משחק מדמה את הפעולות של שחקן אמיתי, וכשמריצים אותה ב-Test Lab, היא מספקת דרך מהירה וניתנת להרחבה כדי לוודא שהמשחק פועל בצורה טובה עבור המשתמשים.

בדף הזה מוסבר איך להריץ בדיקה של לולאת משחק, ואז לראות ולנהל את תוצאות הבדיקה בדף Test Lab במסוף Firebase. אפשר גם להתאים אישית את הבדיקות באמצעות תכונות אופציונליות, כמו כתיבת תוצאות בדיקה בהתאמה אישית או סיום הבדיקה לפני הזמן.

מהו מבחן של לולאת משחק?

לולאה היא הרצה מלאה או חלקית של הבדיקה באפליקציית המשחקים. אפשר להריץ בדיקת לולאת משחק באופן מקומי בסימולטור או בקבוצת מכשירים ב-Test Lab. אפשר להשתמש בבדיקות של לולאות משחק כדי:

  • משחקים במשחק כמו משתמש קצה. אפשר לתכנת את הקלט של המשתמש, לאפשר למשתמש להיות לא פעיל או להחליף את המשתמש ב-AI (לדוגמה, אם הטמעתם AI במשחק מרוצי מכוניות, אתם יכולים להציב נהג AI שאחראי על הקלט של המשתמש).

  • כדי לגלות אילו מכשירים יכולים לתמוך בהגדרה הזו, מריצים את המשחק בהגדרת האיכות הגבוהה ביותר.

  • מריצים בדיקה טכנית, כמו קומפילציה של כמה הצללות, הפעלה שלהן ובדיקה שהפלט הוא כמו שציפיתם.

שלב 1: רישום סכימת כתובות URL מותאמת אישית של Test Lab

קודם כול, צריך לרשום את Firebase Test Labסכימת כתובות ה-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 CLI. אם עדיין לא עשיתם זאת, צריך ליצור קובץ IPA לאפליקציה (תצטרכו לאתר אותו בהמשך).

הרצת בדיקה במסוף Firebase

  1. אם עדיין לא עשיתם זאת, פותחים את מסוף Firebase ויוצרים פרויקט.

  2. בדף Test Lab במסוף Firebase, לוחצים על Run Your First Test > Run an iOS Game Loop (הפעלת הבדיקה הראשונה > הפעלת לולאת משחק ב-iOS).

  3. בקטע Upload App (העלאת אפליקציה), לוחצים על Browse (עיון) ואז בוחרים את קובץ ה-IPA של האפליקציה (אם עדיין לא עשיתם זאת, צריך ליצור קובץ IPA לאפליקציה).

  4. אופציונלי: אם רוצים להריץ כמה לולאות (תרחישים) בו-זמנית או לבחור לולאות ספציפיות להרצה, מזינים את מספרי הלולאות בשדה Scenarios.

    לדוגמה, אם מזינים את הערך 1-3, 5, הפונקציה Test Lab תפעיל את הלולאות 1, 2, 3 ו-5. כברירת מחדל (אם לא מזינים כלום בשדה תרחישים), הפקודה Test Lab מריצה רק את לולאה 1.

  5. בקטע מכשירים, בוחרים מכשיר פיזי אחד או יותר שרוצים לבדוק עליו את האפליקציה, ואז לוחצים על התחלת הבדיקות.

הפעלת בדיקה באמצעות ה-CLI של gcloud beta

  1. אם עדיין לא עשיתם זאת, אתם צריכים להגדיר את סביבת gcloud SDK המקומית, ואז לוודא שאתם מתקינים את רכיב הבטא של gcloud.

  2. מריצים את הפקודה gcloud beta firebase test ios run ומשתמשים בדגלים הבאים כדי להגדיר את הריצה:

סימון לבדיקה של לולאות משחק
--type

חובה: מציינים את סוג הבדיקה ל-iOS שרוצים להריץ. אפשר להזין את סוגי הבדיקות xctest (ברירת מחדל) או game-loop.

--app

חובה: נתיב מוחלט (Google Cloud Storage או מערכת קבצים) לקובץ ה-IPA של האפליקציה. הדגל הזה תקף רק כשמריצים בדיקות של Game Loop.

--scenario-numbers

הלולאות (או התרחישים) שרוצים להריץ באפליקציה. אפשר להזין לולאה אחת, רשימה של לולאות או טווח של לולאות. ברירת המחדל של הלולאה היא 1.

לדוגמה, --scenario-numbers=1-3,5 מפעיל את הלולאות 1, 2, 3 ו-5.

--device-model

המכשיר הפיזי שבו רוצים להריץ את הבדיקה (כאן אפשר לראות אילו מכשירים זמינים אפשר להשתמש).

--timeout

משך הזמן המקסימלי שבו רוצים להריץ את הבדיקה. אפשר להזין מספר שלם כדי לציין את משך הזמן בשניות, או מספר שלם וערך מתוך רשימה כדי לציין את משך הזמן כיחידת זמן ארוכה יותר.

לדוגמה:

  • --timeout=200 מאלץ את הבדיקה להסתיים כשהיא מגיעה ל-200 שניות.
  • --timeout=1h מאלץ את הבדיקה להסתיים כשהיא מגיעה לשעה.

לדוגמה, הפקודה הבאה מריצה בדיקת Game Loop שמבצעת לולאות 1, 4, 6, 7 ו-8 באייפון 8 פלוס:

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 CLI זמין במאמרי העזרה.

הרצת בדיקה באופן מקומי

כדי להריץ את הבדיקה באופן מקומי, טוענים את אפליקציית המשחק בסימולטור ומריצים את הפקודה:

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

סיום מוקדם של בדיקה

כברירת מחדל, בדיקה של לולאות משחק ממשיכה לפעול עד שהיא מגיעה לזמן קצוב לתפוגה של חמש דקות, גם כשכל הלולאות כבר בוצעו. כשהזמן הקצוב מסתיים, הבדיקה מסתיימת וכל הלולאות שממתינות לביצוע מבוטלות. כדי להריץ את הבדיקה מהר יותר או לסיים אותה לפני הזמן, אפשר לקרוא ל-Test Labcustom URL scheme של 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) {}];
}

בדיקת Game Loop מסיימת את הלולאה הנוכחית ומבצעת את הלולאה הבאה. הבדיקה מסתיימת כשאין יותר לולאות להפעלה.

כתיבת תוצאות בדיקה בהתאמה אישית

אתם יכולים להגדיר את בדיקת Game Loop כך שתכתוב תוצאות בדיקה מותאמות אישית למערכת הקבצים של המכשיר. כך, כשהבדיקה מתחילה לפעול, 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];
        }
    }