เริ่มต้นใช้งานการทดสอบ 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: ลงทะเบียน URL Scheme ที่กำหนดเองของ Test Lab

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

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

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

  3. ในช่อง URL Schemes ให้ป้อน firebase-game-loop นอกจากนี้ คุณยังลงทะเบียน URL Scheme ที่กำหนดเองได้โดยเพิ่มลงในไฟล์การกำหนดค่า 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 Scheme ที่กำหนดเองหลายรายการที่ลงทะเบียนไว้ และคุณวางแผนที่จะเรียกใช้หลายลูป (หรือที่เรียกว่าสถานการณ์) ในการทดสอบ คุณต้องระบุลูปที่ต้องการเรียกใช้ในแอปเมื่อเปิดตัว

ใน App Delegate ให้ลบล้างเมธอด 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 Scheme ที่กำหนดเอง ดังนี้

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

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

  1. ในคอนโซล Firebase ให้ไปที่ DevOps และการมีส่วนร่วม > Test Lab

  2. คลิกเรียกใช้การทดสอบครั้งแรก > เรียกใช้ Game Loop ของ iOS

  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

ต้องระบุ: Absolute Path (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 ชั่วโมง

ตัวอย่างเช่น คำสั่งต่อไปนี้จะเรียกใช้การทดสอบ 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 รายการเท่านั้นเมื่อทำการทดสอบในเครื่อง เช่น หากต้องการเรียกใช้ลูป 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 จะทำงานต่อไปจนกว่าจะหมดเวลา 5 นาที แม้ว่าจะมีการดำเนินการลูปทั้งหมดแล้วก็ตาม เมื่อถึงระยะหมดเวลา การทดสอบจะสิ้นสุดลงและยกเลิกการวนซ้ำที่รอดำเนินการ คุณสามารถเร่งการทดสอบหรือสิ้นสุดการทดสอบก่อนกำหนดได้โดยเรียกใช้ URL Scheme ที่กำหนดเอง firebase-game-loop-complete ของ Test Lab ใน 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. เพิ่มโค้ดต่อไปนี้จากที่ใดก็ได้ในโค้ดของแอป (เช่น App Delegate)

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