เริ่มต้นใช้งานการทดสอบ Game Loop สำหรับ iOS

ด้วยการทดสอบ Game Loop คุณสามารถเขียนการทดสอบดั้งเดิมสำหรับเอ็นจิ้นเกมของคุณ จากนั้นเรียกใช้การทดสอบใน Test Lab บนอุปกรณ์ที่คุณเลือก ด้วยวิธีนี้ คุณไม่จำเป็นต้องกังวลเกี่ยวกับการเขียน UI หรือเฟรมเวิร์กการทดสอบที่แตกต่างกัน การทดสอบ Game Loop จำลองการกระทำของผู้เล่นจริง และเมื่อคุณเรียกใช้บน Test Lab จะมอบวิธีที่รวดเร็วและปรับขนาดได้ในการตรวจสอบว่าเกมของคุณทำงานได้ดีสำหรับผู้ใช้ของคุณ

หน้านี้แสดงวิธีรันการทดสอบ Game Loop จากนั้นดูและจัดการผลการทดสอบในหน้า Test Lab ของคอนโซล Firebase คุณยังสามารถปรับแต่งการทดสอบของคุณเพิ่มเติมด้วยคุณสมบัติเสริม เช่น การเขียนผลการทดสอบที่กำหนดเอง หรือ การสิ้นสุดการทดสอบก่อนกำหนด

การทดสอบ Game Loop คืออะไร?

การวนซ้ำคือการทดสอบทั้งหมดหรือบางส่วนในแอปเกมของคุณ คุณสามารถรันการทดสอบ Game Loop ภายในเครื่องบนเครื่องจำลองหรือชุดอุปกรณ์ใน Test Lab การทดสอบ Game Loop สามารถใช้เพื่อ:

  • เล่นเกมของคุณให้จบในฐานะที่ผู้ใช้ปลายทางจะเล่นเกมนั้น คุณสามารถเขียนสคริปต์อินพุตของผู้ใช้ ปล่อยให้ผู้ใช้ไม่ได้ใช้งาน หรือแทนที่ผู้ใช้ด้วย AI (เช่น หากคุณใช้ AI ในเกมแข่งรถ คุณสามารถให้ไดรเวอร์ AI รับผิดชอบอินพุตของผู้ใช้ได้) .

  • รันเกมของคุณด้วยการตั้งค่าคุณภาพสูงสุดเพื่อดูว่าอุปกรณ์ใดบ้างที่สามารถรองรับได้

  • เรียกใช้การทดสอบทางเทคนิค เช่น รวบรวมเชเดอร์หลายตัว ดำเนินการ และตรวจสอบว่าเอาต์พุตเป็นไปตามที่คาดไว้

ขั้นตอนที่ 1: ลงทะเบียน Scheme URL ที่กำหนดเองของ Test Lab

ขั้นแรก คุณต้องลงทะเบียน Scheme URL ที่กำหนดเองของ Firebase Test Lab ในแอปของคุณ:

  1. ใน Xcode ให้เลือกเป้าหมายโปรเจ็กต์

  2. คลิกแท็บ ข้อมูล จากนั้นเพิ่ม ประเภท URL ใหม่

  3. ในช่อง URL Schemes ให้ป้อน firebase-game-loop คุณยังสามารถลงทะเบียน Scheme 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:) :

สวิฟท์

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
}

วัตถุประสงค์-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 ที่กำหนดเอง:

สวิฟท์

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).
}

วัตถุประสงค์-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: สร้างและเรียกใช้การทดสอบ

หลังจากที่คุณลงทะเบียน Scheme URL ที่กำหนดเองของ Test Lab แล้ว คุณจะทำการทดสอบได้ใน คอนโซล Firebase หรือด้วย gcloud beta CLI หากคุณยังไม่ได้สร้างไฟล์ IPA สำหรับแอปของคุณ (คุณจะต้องค้นหาในภายหลัง)

ทำการทดสอบในคอนโซล Firebase

  1. หากคุณยังไม่ได้ดำเนินการ ให้เปิด คอนโซล Firebase และสร้างโปรเจ็กต์

  2. ในหน้า Test Lab ของคอนโซล Firebase คลิก เรียกใช้การทดสอบครั้งแรกของคุณ > เรียกใช้ iOS Game Loop

  3. ในส่วน อัปโหลดแอป คลิก เรียกดู จากนั้นเลือกไฟล์ IPA ของแอปของคุณ (หากคุณยังไม่ได้ สร้างไฟล์ IPA สำหรับแอปของคุณ)

  4. ทางเลือก : หากคุณต้องการรันหลายลูป (หรือที่เรียกว่าสถานการณ์) ในแต่ละครั้ง หรือเลือกลูปที่ต้องการรัน ให้ป้อนหมายเลขลูปในช่อง สถานการณ์

    ตัวอย่างเช่น เมื่อคุณป้อน "1-3, 5" Test Lab จะเรียกใช้ลูป 1, 2, 3 และ 5 ตามค่าเริ่มต้น (หากคุณไม่ป้อนสิ่งใดใน ฟิลด์สถานการณ์ ) Test Lab จะรันเฉพาะลูป 1

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

ทำการทดสอบด้วย gcloud beta CLI

  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 บังคับให้การทดสอบของคุณยุติเมื่อดำเนินการนานถึงหนึ่งชั่วโมง

ตัวอย่างเช่น คำสั่งต่อไปนี้รันการทดสอบ Game Loop ที่ดำเนินการลูป 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 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

สิ้นสุดการทดสอบก่อนกำหนด

ตามค่าเริ่มต้น การทดสอบ Game Loop จะทำงานต่อไปจนกว่าจะหมดเวลาห้านาที แม้ว่าลูปทั้งหมดจะดำเนินการแล้วก็ตาม เมื่อถึงระยะหมดเวลา การทดสอบจะสิ้นสุดและยกเลิกลูปที่ค้างอยู่ คุณสามารถเร่งความเร็วการทดสอบหรือสิ้นสุดก่อนกำหนดได้โดยการเรียก Scheme URL ที่กำหนดเองของ Test Lab firebase-game-loop-complete ใน AppDelegate ของแอปของคุณ ตัวอย่างเช่น:

สวิฟท์

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

วัตถุประสงค์-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. จากที่ใดก็ได้ในโค้ดของแอปของคุณ (เช่น ผู้รับมอบสิทธิ์แอปของคุณ) ให้เพิ่มสิ่งต่อไปนี้:

    สวิฟท์

    /// 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.
      }
    }
    

    วัตถุประสงค์-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];
        }
    }