قد يكون من الصعب أتمتة اختبار الألعاب عندما يتم إنشاء تطبيقات الألعاب على أُطر واجهة مستخدم مختلفة. تسمح لك اختبارات "حلقة الألعاب" بدمج اختباراتك الأصلية مع 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:):
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:).
}
}
عند تشغيل حلقات متعددة في اختبارك، يتم تمرير الحلقة الحالية كمعلَمة إلى عنوان 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).
}
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مخطّط 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)
}
Objective-C
- (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.من أي مكان في رمز تطبيقك (مثل مفوّض التطبيق)، أضِف ما يلي:
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]; } }
الخطوة 3: توقيع تطبيقك
تأكَّد من توقيع جميع البيانات في التطبيق. على سبيل المثال، يمكنك إجراء ذلك من خلال Xcode عن طريق تحديد إعدادات التوقيع، مثل ملفات الإعداد والهوية. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة توقيع الرموز في Apple.
الخطوة 4: تجميع تطبيقك لتحميله
أنشئ ملف IPA لتطبيقك (ستحتاج إلى تحديد موقعه لاحقًا).
من القائمة المنسدلة التي تظهر، انقر على المنتج > الأرشيف. اختَر أحدث أرشيف، ثم انقر على توزيع التطبيق.
في النافذة التي تظهر، انقر على التطوير > التالي.
انقر على تصدير، ثم أدخِل دليلاً تريد تنزيل ملف IPA لتطبيقك فيه.
الخطوة 5: التحقّق من توقيع التطبيق
- تحقَّق من توقيع التطبيق عن طريق فك ضغط ملف .ipa، ثم تشغيل
codesign --verify --deep --verbose /path/to/MyApp.appحيث "MyApp" هو اسم التطبيق داخل المجلد الذي تم فك ضغطه (يختلف لكل مشروع). الناتج المتوقّع هوMyApp.app: valid on disk.
الخطوة 6: تشغيل اختبارك محليًا
يمكنك تشغيل اختبارك محليًا للتحقّق من سلوكه قبل تشغيله باستخدام Test Lab. لاختبار لعبة على الأجهزة الجوّالة محليًا، حمِّلها في محاكي وشغِّل:
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=1xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=2xcrun simctl openurl SIMULATOR_UDID firebase-game-loop://?scenario=5
الخطوات التالية
شغِّل اختبارك باستخدام Firebase Console أو gcloud CLI.