قد يكون من الصعب التشغيل التلقائي لاختبار الألعاب عندما تكون تطبيقات الألعاب مبنية على أُطر عمل مختلفة لواجهة المستخدم. تتيح لك اختبارات 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:)
:
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).
}
}
}
إنهاء اختبار مبكرًا
يستمر اختبار حلقة الألعاب تلقائيًا في التشغيل إلى أن يصل إلى مهلة
مدتها خمس دقائق، حتى بعد تنفيذ جميع الحلقات. عند بلوغ مهلة الانتظار، ينتهي الاختبار ويلغى أي حلقات في انتظار المراجعة. يمكنك تسريع
الاختبار أو إنهائه مبكرًا من خلال استدعاء مخطّط عنوان URL المخصّص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]; } }
الخطوة 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 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
الخطوات التالية
يمكنك إجراء الاختبار باستخدام وحدة تحكّم Firebase أو واجهة سطر أوامر gcloud.