خودکارسازی تست بازی وقتی برنامههای بازی روی چارچوبهای رابط کاربری مختلف ساخته میشوند، میتواند دشوار باشد. تستهای حلقه بازی به شما این امکان را میدهند که تستهای بومی خود را با Test Lab ادغام کنید و به راحتی آنها را روی دستگاههایی که انتخاب میکنید اجرا کنید. این راهنما نحوه آمادهسازی یک تست حلقه بازی برای اجرا با استفاده از Firebase Test Lab را شرح میدهد.
درباره تستهای حلقه بازی
تست حلقه بازی چیست؟
تست حلقه بازی، اعمال یک بازیکن واقعی را شبیهسازی میکند تا تأیید کند که بازی شما به سرعت و مقیاسپذیر برای کاربران شما عملکرد خوبی دارد. یک حلقه، اجرای کامل یا جزئی تست شما روی برنامه بازی شماست. میتوانید تست حلقه بازی را به صورت محلی روی یک شبیهساز یا روی مجموعهای از دستگاهها در Test Lab اجرا کنید. تستهای حلقه بازی را میتوان برای موارد زیر استفاده کرد:
- بازی خود را همانطور که یک کاربر نهایی آن را بازی میکند، اجرا کنید. میتوانید ورودی کاربر را اسکریپت کنید، بگذارید کاربر بیکار باشد، یا کاربر را با یک هوش مصنوعی جایگزین کنید (برای مثال، اگر هوش مصنوعی را در یک بازی مسابقه اتومبیلرانی پیادهسازی کردهاید، میتوانید یک راننده هوش مصنوعی را مسئول ورودی کاربر قرار دهید).
- بازی خود را با بالاترین کیفیت اجرا کنید تا ببینید کدام دستگاهها میتوانند از آن پشتیبانی کنند.
- یک تست فنی اجرا کنید، مانند کامپایل کردن چندین شیدر، اجرای آنها و بررسی اینکه خروجی مطابق انتظار است.
مرحله ۱ : ثبت طرح URL سفارشی Test Lab
در Xcode، یک هدف پروژه انتخاب کنید.
روی برگه اطلاعات کلیک کنید، سپس یک نوع URL جدید اضافه کنید.
در فیلد طرحهای 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 پیکربندی شده است.
مرحله ۲ : به صورت اختیاری برنامه خود را پیکربندی کنید
اجرای چندین حلقه
اگر قصد دارید چندین حلقه (یا سناریو) را در تست خود اجرا کنید، باید در زمان اجرا مشخص کنید که میخواهید کدام حلقهها در برنامه شما اجرا شوند.
در نماینده برنامه خود، متد 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
}
هدف-سی
- (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).
}
هدف-سی
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).
}
}
}
پایان دادن زودهنگام به آزمون
به طور پیشفرض، یک تست حلقه بازی (Game Loop) تا زمانی که به زمان انقضای پنج دقیقه برسد، حتی زمانی که تمام حلقهها اجرا شده باشند، به اجرا ادامه میدهد. وقتی به زمان انقضای پنج دقیقه رسید، تست پایان مییابد و هر حلقه در حال انتظاری را لغو میکند. میتوانید با فراخوانی طرح URL سفارشی firebase-game-loop-complete از Test Lab در AppDelegate برنامه خود، تست خود را سرعت بخشیده یا آن را زودتر به پایان برسانید. برای مثال:
سویفت
/// End the loop by calling our custom url scheme.
func finishLoop() {
let url = URL(string: "firebase-game-loop-complete://")!
UIApplication.shared.open(url)
}
هدف-سی
- (void)finishLoop {
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"firebase-game-loop-complete://"]
options:@{}
completionHandler:^(BOOL success) {}];
}
تست حلقه بازی شما حلقه فعلی را خاتمه داده و حلقه بعدی را اجرا میکند. وقتی حلقه دیگری برای اجرا وجود نداشته باشد، تست به پایان میرسد.
نوشتن نتایج تست سفارشی
شما میتوانید تست حلقه بازی خود را طوری پیکربندی کنید که نتایج تست سفارشی را در سیستم فایل دستگاه شما بنویسد. به این ترتیب، وقتی تست شروع به اجرا میکند، 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. } }هدف-سی
/// 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 Codesigning مراجعه کنید.
مرحله ۴ : بستهبندی برنامه برای آپلود
یک فایل IPA برای برنامه خود ایجاد کنید (بعداً باید آن را پیدا کنید).
از منوی کشویی که ظاهر میشود، روی محصول > بایگانی کلیک کنید. جدیدترین بایگانی را انتخاب کنید، سپس روی توزیع برنامه کلیک کنید.
در پنجرهای که ظاهر میشود، روی توسعه > بعدی کلیک کنید.
روی Export کلیک کنید، سپس دایرکتوریای را که میخواهید فایل 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پیدا کنید.اگر فقط یک شبیهساز در حال اجرا است، به جای SIMULATOR_UDID رشتهی ویژهی
"booted"را وارد کنید.
اگر تست شما شامل چندین حلقه است، میتوانید با ارسال شماره حلقه به پرچم 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 اجرا کنید.