Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

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

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

  2. ในหน้าห้องปฏิบัติการทดสอบของ Firebase คอนโซลคลิกเรียกใช้การทดสอบครั้งแรกของคุณ> เรียกใช้ iOS เกมห่วง

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

  4. เลือก: ถ้าคุณต้องการที่จะทำงานหลายลูป (aka สถานการณ์) ได้ตลอดเวลาหรือเลือกลูปที่เฉพาะเจาะจงเพื่อวิ่งป้อนหมายเลขห่วงในฟิลด์สถานการณ์

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

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

ทำการทดสอบด้วย 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

สำหรับข้อมูลเพิ่มเติมเกี่ยว CLI GCloud ให้ดูที่ เอกสารอ้างอิง

เรียกใช้การทดสอบในพื้นที่

หากต้องการเรียกใช้การทดสอบในเครื่อง ให้โหลดแอปเกมในโปรแกรมจำลองและเรียกใช้:

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 ที่กำหนดเองห้องปฏิบัติการทดสอบของ 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 ของคุณเพื่อเขียนผลการทดสอบที่กำหนดเองไปยังระบบไฟล์ของอุปกรณ์ของคุณ วิธีนี้เมื่อการทดสอบเริ่มทำงานร้านค้าห้องปฏิบัติการทดสอบไฟล์ผลใน GameLoopsResults ไดเรกทอรีบนอุปกรณ์ทดสอบของคุณ (ซึ่งคุณต้องสร้างตัวเอง) เมื่อทดสอบปลายห้องปฏิบัติการทดสอบย้ายไฟล์ทั้งหมดจาก GameLoopResults ไดเรกทอรีถังของโครงการ โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อตั้งค่าการทดสอบของคุณ:

  • ไฟล์ผลลัพธ์ทั้งหมดจะถูกอัปโหลดโดยไม่คำนึงถึงประเภทไฟล์ ขนาด หรือปริมาณ

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

ในการตั้งค่าการทดสอบของคุณเพื่อเขียนผลการทดสอบที่กำหนดเอง:

  1. ใน app ของ 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];
        }
    }