وقتی برنامههای بازی در چارچوبهای واسط کاربر متفاوتی ساخته میشوند، خودکارسازی آزمایش بازی میتواند دشوار باشد. آزمایشهای «حلقه بازی» به شما امکان میدهد آزمایشهای بومیتان را با Test Lab ادغام کنید و بهراحتی آنها را در دستگاههای انتخابیتان اجرا کنید. این راهنما نحوه آمادهسازی آزمایش «حلقه بازی» را برای اجرا بااستفاده از Firebase Test Lab شرح میدهد.
درباره آزمایشهای Game Loop
آزمون Game Loop چیست؟
آزمون «حلقه بازی» کنشهای بازیکن واقعی را شبیهسازی میکند تا تأیید کند بازیتان بهسرعت و بهطور مقیاسپذیر برای کاربران عملکرد خوبی دارد. حلقه اجرای کامل یا جزئی آزمایش شما در برنامه بازیتان است. میتوانید آزمایش «حلقه بازی» را بهصورت محلی در شبیهساز یا در مجموعهای از دستگاهها در Test Lab اجرا کنید. از آزمایشهای Game Loop میتوان برای موارد زیر استفاده کرد:
- بازیتان را همانطور که کاربر نهایی بازی میکند اجرا کنید. میتوانید ورودی کاربر را اسکریپتنویسی کنید، کاربر را در حالت غیرفعال قرار دهید، یا کاربر را با هوش مصنوعی جایگزین کنید (برای مثال، اگر هوش مصنوعی را در بازی مسابقه اتومبیلرانی پیادهسازی کردهاید، میتوانید راننده هوش مصنوعی را مسئول ورودی کاربر قرار دهید).
- بازیتان را با بالاترین تنظیم کیفیت اجرا کنید تا ببینید کدام دستگاهها میتوانند از آن پشتیبانی کنند.
- آزمایش فنی اجرا کنید، مثلاً چند سایهزن را کامپایل کنید، آنها را اجرا کنید، و بررسی کنید که خروجی مطابق انتظار باشد.
مرحله ۱: ثبت طرحواره نشانی وب سفارشی Test Lab
در Xcode، هدف پروژه را انتخاب کنید.
روی برگه اطلاعات کلیک کنید، سپس نوع نشانی وب جدیدی اضافه کنید.
در فیلد طرحوارههای نشانی وب،
firebase-game-loopرا وارد کنید. همچنین میتوانید طرحواره نشانی وب سفارشی را با افزودن آن به فایل پیکربندی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 پیکربندی شده است.
مرحله ۲: درصورت تمایل، برنامهتان را پیکربندی کنید
اجرای چند حلقه
اگر قصد دارید چند حلقه (یا سناریو) را در آزمایشتان اجرا کنید، باید مشخص کنید کدام حلقهها را میخواهید در زمان راهاندازی در برنامهتان اجرا کنید.
در نماینده برنامهتان، روش 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 <UIApplicationOpenURLOptionsKey, id> *)options {
if ([url.scheme isEqualToString:(@"firebase-game-loop")]) {
// ...Enter Game Loop Test logic to override application(_:open:options:).
}
}
وقتی چندین حلقه را در آزمایشتان اجرا میکنید، حلقه فعلی بهعنوان پارامتر به نشانی وب مورداستفاده برای راهاندازی برنامه ارسال میشود. همچنین میتوانید با تجزیه کردن شیء URLComponents مورداستفاده برای واکشی طرحواره نشانی وب سفارشی، شماره حلقه فعلی را دریافت کنید:
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).
}
}
}
پایان دادن زودهنگام به آزمایش
بهطور پیشفرض، آزمایش «حلقه بازی» تا زمانی که به زمان استراحت پنج دقیقهای برسد، به اجرا ادامه میدهد، حتی زمانی که همه حلقهها اجرا شده باشند. وقتی
زمان وقفه بهپایان میرسد، آزمایش تمام میشود و هرگونه حلقه معلق لغو میشود. با فراخوانی طرحواره نشانی وب سفارشی 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)
}
Objective-C
- (void)finishLoop {
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
options:@{}
completionHandler:^(BOOL success) {}];
}
آزمایش «حلقه بازی» شما حلقه فعلی را خاتمه میدهد و حلقه بعدی را اجرا میکند. وقتی حلقه دیگری برای اجرا وجود نداشته باشد، آزمایش بهپایان میرسد.
نوشتن نتایج آزمایش سفارشی
میتوانید آزمایش Game Loop را پیکربندی کنید تا نتایج آزمایش سفارشی را در سیستم فایل دستگاهتان بنویسد. بهاینترتیب، وقتی آزمایش شروع به اجرا میکند، Test Lab
فایلهای نتیجه را در دایرکتوری GameLoopsResults در دستگاه آزمایشیتان (که باید خودتان ایجاد کنید) ذخیره میکند. وقتی آزمایش بهپایان میرسد، Test Lab
همه فایلها را از دایرکتوری GameLoopResults به سطل پروژه شما منتقل میکند. هنگام راهاندازی آزمایشتان، موارد زیر را درنظر داشته باشید:
همه فایلهای نتیجه بدون درنظر گرفتن نوع، اندازه، یا تعداد فایل بارگذاری میشوند.
Test Lab نتایج آزمایشتان را تا زمانی که همه حلقههای آزمایشتان اجرا نشده باشند پردازش نمیکند، بنابراین اگر آزمایشتان شامل چندین حلقه است که خروجی را مینویسند، مطمئن شوید که آنها را به فایل نتیجه منحصربهفردی اضافه میکنید یا برای هر حلقه یک فایل نتیجه ایجاد میکنید. بهاینترتیب، میتوانید از رونویسی نتایج حاصل از حلقه قبلی جلوگیری کنید.
برای راهاندازی آزمایشتان برای نوشتن نتایج آزمایش سفارشی:
در فهرست راهنمای
Documentsبرنامهتان، فهرست راهنمایی با نامGameLoopResultsایجاد کنید.از هرجایی در کد برنامهتان (مثلاً، نماینده برنامهتان)، موارد زیر را اضافه کنید:
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]; } }
مرحله ۳: امضا کردن برنامه
مطمئن شوید همه آرتیفکتهای برنامه امضا شده باشند. برای مثال، میتوانید این کار را ازطریق Xcode با مشخص کردن تنظیمات امضا مانند نمایه تدارک و هویت انجام دهید. برای اطلاعات بیشتر، به امضای کد Apple مراجعه کنید
مرحله ۴: بستهبندی برنامه برای بارگذاری
یک فایل IPA برای برنامهتان تولید کنید (بعداً باید آن را پیدا کنید).
از منوِ کرکرهای که ظاهر میشود، روی محصول > بایگانی کلیک کنید. جدیدترین بایگانی را انتخاب کنید، سپس روی توزیع برنامه کلیک کنید.
در پنجرهای که نشان داده میشود، روی توسعه > بعدی کلیک کنید.
روی صادر کردن کلیک کنید، سپس دایرکتوریای را که میخواهید فایل IPA برنامهتان در آن بارگیری شود وارد کنید.
مرحله ۵: درستیسنجی امضای برنامه
- امضای برنامه را با از حالت فشرده خارج کردن فایل .ipa و سپس اجرای
codesign --verify --deep --verbose /path/to/MyApp.appدرستیسنجی کنید که در آن «MyApp» نام برنامه در پوشه از حالت فشرده خارجشده است (برای هر پروژه متفاوت است). خروجی موردانتظارMyApp.app: valid on diskاست.
مرحله ۶: اجرای آزمایش بهصورت محلی
میتوانید آزمایشتان را بهصورت محلی اجرا کنید تا رفتار آن را قبلاز اجرا با Test Lab بررسی کنید. برای آزمایش محلی، برنامه بازی تلفن خود را در شبیهساز بار کنید و این دستور را اجرا کنید:
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://
میتوانید UDID شبیهسازتان را با اجرای فرمان
instruments -s devicesپیدا کنید.اگر فقط یک شبیهساز درحال اجرا است، رشته ویژه
"booted"را بهجای SIMULATOR_UDID وارد کنید.
اگر آزمایشتان حاوی چند حلقه است، میتوانید با ارسال شماره حلقه به پرچم scenario،
مشخص کنید کدام حلقه اجرا شود. توجه داشته باشید که هنگام اجرای محلی آزمایش،
فقط میتوانید یک حلقه را در هر زمان اجرا کنید. برای مثال، اگر میخواهید
حلقههای ۱، ۲، و ۵ را اجرا کنید، باید برای هر حلقه فرمان جداگانهای اجرا کنید:
xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=1xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5
مراحل بعدی
آزمایش را بااستفاده از کنسول Firebase یا gcloud CLI اجرا کنید.