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

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

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

מהו בדיקת לולאת משחק?

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

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

  • כדאי להפעיל את המשחק בהגדרת האיכות הגבוהה ביותר כדי לבדוק אילו מכשירים יכולים לתמוך בו.

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

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

קודם כול צריך לרשום באפליקציה את סכמת כתובת ה-URL המותאמת אישית של Firebase Test Lab:

  1. ב-Xcode, בוחרים יעד פרויקט.

  2. לוחצים על הכרטיסייה Info (מידע) ומוסיפים סוג כתובת 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 או באמצעות ה-CLI של gcloud בגרסת בטא. אם עדיין לא עשיתם זאת, יוצרים קובץ 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. כברירת מחדל (אם לא מזינים שום דבר בשדה Scenarios), הפונקציה Test Lab מפעילה רק את הלולאה 1.

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

הפעלת בדיקה באמצעות ה-CLI של gcloud בגרסת בטא

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

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

דגלים לבדיקות של Game Loop
--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 מאלץ את הבדיקה להסתיים אחרי שעה.

לדוגמה, הפקודה הבאה מריצה בדיקה של לולאת משחקים שמבצעת לולאות 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

מידע נוסף על ה-CLI של 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

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

כברירת מחדל, בדיקת Game Loop ממשיכה לפעול עד שהיא מגיעה לזמן קצוב של חמש דקות, גם אם כל הלולאות בוצעו. כשהזמן יפוג, הבדיקה תסתיים וכל לולאות בהמתנה יבוטלו. אפשר להאיץ את הבדיקה או לסיים אותה מוקדם יותר על ידי קריאה לסכימה של כתובת ה-URL המותאמת אישית של Test Lab firebase-game-loop-complete ב-Appהענקת הגישה. לדוגמה:

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 מסיימת את הלולאה הנוכחית ומפעילה את הלולאה הבאה. כשאין יותר לולאות להפעלה, הבדיקה מסתיימת.

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

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

  • כל קובצי התוצאות יועלמו, ללא קשר לסוג, לגודל או לכמות שלהם.

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

כדי להגדיר את הבדיקה כך שתכתוב תוצאות בדיקה בהתאמה אישית:

  1. יוצרים ספרייה בשם GameLoopResults בתיקייה Documents של האפליקציה.

  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];
        }
    }