قد يكون من الصعب تنفيذ اختبارات الألعاب آليًا عندما يتم إنشاء تطبيقات الألعاب باستخدام أُطر عمل مختلفة لواجهة المستخدم. تسمح لك اختبارات Game Loop بدمج اختباراتك الأصلية مع Test Lab وإجرائها بسهولة على الأجهزة التي تختارها. يوضّح هذا الدليل كيفية إعداد اختبار "حلقة الألعاب" لتشغيله باستخدام Firebase Test Lab.
لمحة عن اختبارات "حلقة الألعاب"
ما هو اختبار "حلقة الألعاب"؟
يحاكي اختبار "حلقة الألعاب" إجراءات لاعب حقيقي للتحقّق من أنّ لعبتك تعمل بشكل جيد لدى المستخدمين بطريقة سريعة وقابلة للتوسّع. الحلقة هي عملية تشغيل كاملة أو جزئية للاختبار على تطبيق الألعاب. ويمكنك إجراء اختبار "حلقة الألعاب" محليًا على محاكي أو على مجموعة من الأجهزة في Test Lab. يمكن استخدام اختبارات "حلقات الألعاب" في ما يلي:
- جرِّب لعبتك كما لو كنت مستخدمًا نهائيًا. يمكنك إما كتابة نص برمجي لإدخال المستخدم أو ترك المستخدم غير نشط أو استبدال المستخدم بذكاء اصطناعي (على سبيل المثال، إذا نفّذت ذكاءً اصطناعيًا في لعبة سباق سيارات، يمكنك وضع سائق ذكاء اصطناعي مسؤولاً عن إدخال المستخدم).
- شغِّل لعبتك بأعلى إعدادات الجودة لمعرفة الأجهزة التي يمكنها تشغيلها.
- إجراء اختبار فني، مثل تجميع برامج تظليل متعددة وتنفيذها والتأكّد من أنّ الناتج هو كما هو متوقّع
الخطوة 1: تسجيل مخطط عنوان 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.
الخطوة 2: ضبط إعدادات تطبيقك اختياريًا
تشغيل حلقات متعددة
إذا كنت تخطّط لتشغيل حلقات متعدّدة (تُعرف أيضًا باسم السيناريوهات) في اختبارك، عليك تحديد الحلقات التي تريد تشغيلها في تطبيقك عند وقت الإطلاق.
في مفوّض تطبيقك، يمكنك إلغاء طريقة 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).
}
}
}
إنهاء اختبار مبكرًا
يستمر اختبار "حلقة الألعاب" تلقائيًا إلى أن يصل إلى مهلة مدتها خمس دقائق، حتى بعد تنفيذ جميع الحلقات. عند انتهاء المهلة، ينتهي الاختبار ويتم إلغاء أي حلقات معلّقة. يمكنك تسريع اختبارك أو إنهاؤه مبكرًا من خلال استدعاء نظام عناوين URL المخصّص الخاص بـ Test Labfirebase-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)
}
- (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
.من أي مكان في رمز تطبيقك (مثل مفوّض التطبيق)، أضِف ما يلي:
/// 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]; } }
الخطوة 3: توقيع تطبيقك
تأكَّد من توقيع جميع العناصر في التطبيق. على سبيل المثال، يمكنك إجراء ذلك من خلال Xcode عن طريق تحديد إعدادات التوقيع، مثل ملف الإعداد والهوية. لمزيد من المعلومات، يُرجى الاطّلاع على: توقيع Apple
الخطوة 4: إنشاء حِزمة تطبيقك لتحميلها
أنشئ ملف IPA لتطبيقك (ستحتاج إلى تحديد موقعه لاحقًا).
من القائمة المنسدلة التي تظهر، انقر على المنتج > الأرشيف. اختَر أحدث أرشيف، ثم انقر على توزيع التطبيق.
في النافذة التي تظهر، انقر على التطوير > التالي.
اختياري: للحصول على إصدار أسرع، أزِل العلامة من المربّع بجانب الخيار إعادة الإنشاء من رمز Bitcode، ثم انقر على التالي. Test Lab لا يتطلّب تقليل حجم تطبيقك أو إعادة إنشائه لتنفيذ اختبار، لذا يمكنك إيقاف هذا الخيار بأمان.
انقر على تصدير، ثم أدخِل دليلاً تريد تنزيل ملف IPA الخاص بتطبيقك فيه.
الخطوة 5: التحقّق من توقيع التطبيق
- تحقَّق من توقيع التطبيق عن طريق فك ضغط ملف .ipa ثم تشغيل
codesign --verify --deep --verbose /path/to/MyApp.app
حيث "MyApp" هو اسم التطبيق داخل المجلد الذي تم فك ضغطه (يختلف لكل مشروع). الناتج المتوقّع هوMyApp.app: valid on disk
.
الخطوة 6: تشغيل الاختبار على جهازك
يمكنك إجراء الاختبار محليًا للتحقّق من سلوكه قبل إجرائه باستخدام Test Lab. لاختبار التطبيق على جهازك، حمِّل تطبيق الألعاب في محاكي ونفِّذ ما يلي:
xcrun simctl openurlSIMULATOR_UDID firebase-game-loop://
يمكنك العثور على المعرّف الفريد للجهاز (UDID) الخاص بالمحاكي من خلال تنفيذ الأمر
instruments -s devices
.إذا كان هناك محاكي واحد فقط قيد التشغيل، أدخِل السلسلة الخاصة
"booted"
بدلاً من SIMULATOR_UDID.
إذا كان الاختبار يتضمّن حلقات متعدّدة، يمكنك تحديد الحلقة التي تريد تشغيلها
من خلال تمرير رقم الحلقة إلى العلامة scenario
. يُرجى العِلم أنّه يمكنك تنفيذ حلقة واحدة فقط في كل مرة عند إجراء الاختبار محليًا. على سبيل المثال، إذا أردت تشغيل الحلقات 1 و2 و5، عليك تشغيل أمر منفصل لكل حلقة:
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.