ทำการทดสอบ Game Loop

การทดสอบเกมโดยอัตโนมัติอาจเป็นเรื่องยากหากแอปเกมสร้างขึ้นบน เฟรมเวิร์ก UI การทดสอบ 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 จะทํางานต่อไปจนกว่าจะถึงระยะหมดเวลา ห้านาที แม้ว่าจะมีการวนซ้ำทั้งหมดแล้วก็ตาม เมื่อ ถึงระยะหมดเวลา การทดสอบจะสิ้นสุดลงและยกเลิกการวนซ้ำทั้งหมดที่รอดำเนินการ เร่งความเร็วได้ ทดสอบให้เสร็จหรือสิ้นสุดการทดสอบก่อนกำหนดโดยการเรียกใช้รูปแบบ 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) {}];
}

การทดสอบ 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 Codesigning

ขั้นตอนที่ 4: จัดแพ็กเกจแอปสำหรับการอัปโหลด

สร้างไฟล์ IPA สำหรับแอป (คุณจะต้องค้นหาในภายหลัง)

  1. จากเมนูแบบเลื่อนลงที่ปรากฏขึ้น ให้คลิกผลิตภัณฑ์ > เก็บ เลือกที่เก็บถาวรล่าสุด แล้วคลิกเผยแพร่แอป

  2. ในหน้าต่างที่ปรากฏขึ้น ให้คลิกการพัฒนา > ถัดไป

  3. ไม่บังคับ: หากต้องการใช้บิลด์ที่เร็วขึ้น ให้ยกเลิกการเลือก ตัวเลือก สร้างใหม่จาก Bitcode แล้วคลิก Next Test Lab คุณไม่จำเป็นต้องทำแอปให้น้อยลงหรือสร้างแอปใหม่เพื่อทำการทดสอบ โปรดปิดใช้งานตัวเลือกนี้อย่างปลอดภัย

  4. คลิกส่งออก แล้วป้อนไดเรกทอรีที่ต้องการดาวน์โหลด ไฟล์ 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 รายการเมื่อเรียกใช้การทดสอบภายในเครื่อง ตัวอย่างเช่น หากคุณ ต้องการเรียกใช้ลูป 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 หรือ gcloud CLI