ด้วยการทดสอบ 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 ในแอปของคุณ:
ใน Xcode เลือกเป้าหมายโครงการ
คลิกแท็บ ข้อมูล จากนั้นเพิ่ม ประเภท URL ใหม่
ในช่อง 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:)
:
สวิฟต์
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 <UIApplicationOpenURLOptionsKey, id> *)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: สร้างและเรียกใช้การทดสอบ
หลังจากลงทะเบียนรูปแบบ URL ที่กำหนดเองของ Test Lab แล้ว คุณจะเรียกใช้การทดสอบใน คอนโซล Firebase หรือด้วย gcloud beta CLI ได้ หากคุณยังไม่ได้ดำเนินการ ให้สร้างไฟล์ IPA สำหรับแอปของคุณ (คุณจะต้องค้นหาในภายหลัง)
ทำการทดสอบในคอนโซล Firebase
หากคุณยังไม่ได้ดำเนินการ ให้เปิด คอนโซล Firebase และสร้างโครงการ
ในหน้า Test Lab ของคอนโซล Firebase ให้คลิก Run Your First Test > Run an iOS Game Loop
ในส่วน อัปโหลดแอป ให้คลิก เรียกดู จากนั้นเลือกไฟล์ IPA ของแอป (หากคุณยังไม่ได้ สร้าง ให้สร้างไฟล์ IPA สำหรับแอปของคุณ)
ทางเลือก : หากคุณต้องการรันหลายลูป (หรือเรียกอีกอย่างว่าสถานการณ์) ในแต่ละครั้งหรือเลือกลูปเฉพาะที่จะรัน ให้ป้อนหมายเลขลูปในช่อง สถานการณ์
ตัวอย่างเช่น เมื่อคุณป้อน "1-3, 5" Test Lab จะวนลูป 1, 2, 3 และ 5 โดยค่าเริ่มต้น (หากคุณไม่ได้ป้อนอะไรในช่อง สถานการณ์ ) Test Lab จะรันเฉพาะลูป 1
ในส่วน อุปกรณ์ ให้เลือกอุปกรณ์จริงอย่างน้อยหนึ่งเครื่องที่คุณต้องการทดสอบแอป จากนั้นคลิก เริ่มการทดสอบ
ทำการทดสอบด้วย gcloud beta CLI
หากคุณยังไม่ได้ดำเนินการ ให้กำหนดค่าสภาพแวดล้อม gcloud SDK ในเครื่องของคุณ จากนั้นตรวจสอบให้แน่ใจว่าได้ติดตั้ง คอมโพเนนต์ gcloud beta แล้ว
รันคำสั่ง
gcloud beta firebase test ios run
และใช้แฟล็กต่อไปนี้เพื่อกำหนดค่าการรัน:
ค่าสถานะสำหรับการทดสอบ Game Loop | |
---|---|
--type | จำเป็น : ระบุประเภทของการทดสอบ iOS ที่คุณต้องการเรียกใช้ คุณสามารถป้อนประเภทการทดสอบ |
--app | จำเป็น : เส้นทางสัมบูรณ์ (Google Cloud Storage หรือระบบไฟล์) ไปยังไฟล์ IPA ของแอป แฟล็กนี้ใช้ได้เมื่อรันการทดสอบ Game Loop เท่านั้น |
--scenario-numbers | ลูป (สถานการณ์สมมติ) ที่คุณต้องการเรียกใช้ในแอปของคุณ คุณสามารถป้อนหนึ่งลูป รายการหรือลูป หรือช่วงของลูป ลูปเริ่มต้นคือ 1 ตัวอย่างเช่น |
--device-model | อุปกรณ์ทางกายภาพที่คุณต้องการเรียกใช้การทดสอบ (ค้นหาว่า อุปกรณ์ใดที่ คุณสามารถใช้ได้) |
--timeout | ระยะเวลาสูงสุดที่คุณต้องการให้การทดสอบทำงาน คุณสามารถป้อนจำนวนเต็มเพื่อแสดงระยะเวลาเป็นวินาที หรือป้อนจำนวนเต็มและการแจงนับเพื่อแสดงระยะเวลาเป็นหน่วยเวลาที่ยาวขึ้น ตัวอย่างเช่น:
|
ตัวอย่างเช่น คำสั่งต่อไปนี้รันการทดสอบ 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 จะทำงานต่อไปจนกว่าจะหมดเวลา 5 นาที แม้ว่าจะมีการเรียกใช้ลูปทั้งหมดแล้วก็ตาม เมื่อหมดเวลา การทดสอบจะสิ้นสุดลงและยกเลิกลูปที่ค้างอยู่ คุณสามารถเร่งความเร็วการทดสอบหรือสิ้นสุดการทดสอบก่อนเวลาได้ด้วยการเรียกรูปแบบ 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 จะไม่ประมวลผลผลการทดสอบของคุณจนกว่าการวนซ้ำทั้งหมดในการทดสอบของคุณจะเสร็จสิ้น ดังนั้นหากการทดสอบของคุณมีหลายลูปที่เขียนเอาต์พุต ตรวจสอบให้แน่ใจว่าคุณผนวกลูปเหล่านั้นเข้ากับไฟล์ผลลัพธ์ที่ไม่ซ้ำกันหรือสร้างไฟล์ผลลัพธ์สำหรับแต่ละลูป ด้วยวิธีนี้ คุณสามารถหลีกเลี่ยงการเขียนทับผลลัพธ์จากลูปก่อนหน้า
ในการตั้งค่าการทดสอบของคุณให้เขียนผลการทดสอบแบบกำหนดเอง:
ในไดเรกทอรี
Documents
ของแอป ให้สร้างไดเรกทอรีชื่อGameLoopResults
จากที่ใดก็ได้ในโค้ดของแอป (เช่น ผู้มอบสิทธิ์แอปของคุณ) ให้เพิ่มสิ่งต่อไปนี้:
สวิฟต์
/// 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]; } }