הרצת בדיקה של Game Loop

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

מידע על בדיקות של game loop

מה זה בדיקת game loop?

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

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

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

  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: הגדרת האפליקציה (אופציונלי)

הפעלת כמה לולאות

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

בנציג האפליקציה, מבטלים את השיטה 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).
        }
    }
}

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

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

שלב 3: חותמים על האפליקציה

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

שלב 4: אריזת האפליקציה להעלאה

יוצרים קובץ IPA לאפליקציה (תצטרכו לאתר אותו בהמשך).

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

  2. בחלון שמופיע, לוחצים על פיתוח > הבא.

  3. לוחצים על Export (ייצוא) ומזינים את הספרייה שבה רוצים להוריד את קובץ ה-IPA של האפליקציה.

שלב 5: אימות חתימת האפליקציה

  1. כדי לאמת את חתימת האפליקציה, צריך לבטל את הדחיסה של קובץ ה-ipa ואז להריץ את הפקודה codesign --verify --deep --verbose /path/to/MyApp.app כאשר MyApp הוא שם האפליקציה בתוך התיקייה שבוטלה הדחיסה שלה (השם משתנה בכל פרויקט). הפלט הצפוי הוא MyApp.app: valid on disk.

שלב 6: הפעלת הבדיקה באופן מקומי

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

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

השלבים הבאים

מריצים את הבדיקה באמצעות מסוף Firebase או ה-CLI של gcloud.