เริ่มต้นการทดสอบ 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 ที่กำหนดเองของ Test Lab

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

  1. ใน Xcode เลือกเป้าหมายโครงการ

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

  3. ในฟิลด์ URL Schemes ให้ป้อน 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
}

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

วัตถุประสงค์-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 หรือด้วย 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. ในส่วน อุปกรณ์ ให้เลือกอุปกรณ์จริงอย่างน้อยหนึ่งเครื่องที่คุณต้องการทดสอบแอปของคุณ จากนั้นคลิก เริ่มการทดสอบ

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

  1. หากคุณยังไม่ได้ทำ ให้กำหนดค่าสภาพแวดล้อม gcloud SDK ในเครื่อง จากนั้นตรวจสอบให้แน่ใจว่าได้ติดตั้ง คอมโพเนนต์ gcloud beta

  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 จะยังคงทำงานต่อไปจนกว่าจะหมดเวลาห้านาที แม้ว่าจะดำเนินการวนซ้ำทั้งหมดแล้วก็ตาม เมื่อหมดเวลา การทดสอบจะสิ้นสุดลงและยกเลิกลูปที่ค้างอยู่ คุณสามารถเพิ่มความเร็วในการทดสอบหรือสิ้นสุดการทดสอบก่อนกำหนดได้โดยการเรียกรูปแบบ 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)
}

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

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