من خلال اختبارات Game Loop ، يمكنك كتابة اختبارات أصلية لمحرك اللعبة الخاص بك ثم تشغيلها في Test Lab على الأجهزة التي تختارها. بهذه الطريقة ، لا داعي للقلق بشأن الكتابة لواجهة مستخدم مختلفة أو إطارات اختبار. يحاكي اختبار Game Loop تصرفات لاعب حقيقي ، وعندما تقوم بتشغيله في Test Lab ، فإنه يوفر طريقة سريعة وقابلة للتطوير للتحقق من أن لعبتك تؤدي أداءً جيدًا لمستخدميك.
توضح لك هذه الصفحة كيفية تشغيل اختبار Game Loop ، ثم عرض نتائج الاختبار وإدارتها في صفحة Test Lab بوحدة تحكم Firebase. يمكنك أيضًا تخصيص اختباراتك بميزات اختيارية ، مثل كتابة نتائج اختبار مخصصة أو إنهاء اختبارك مبكرًا .
ما هو اختبار حلقة اللعبة؟
الحلقة هي عملية تشغيل كاملة أو جزئية لاختبارك على تطبيق الألعاب الخاص بك. يمكنك إجراء اختبار Game Loop محليًا على جهاز محاكاة أو على مجموعة من الأجهزة في Test Lab. يمكن استخدام اختبارات Game Loop من أجل:
قم بتشغيل اللعبة الخاصة بك حيث سيلعبها المستخدم النهائي. يمكنك إما كتابة إدخال المستخدم ، أو السماح للمستخدم بالتوقف عن العمل ، أو استبدال المستخدم بـ AI (على سبيل المثال ، إذا قمت بتطبيق AI في لعبة سباق سيارات ، فيمكنك وضع سائق AI مسؤولاً عن مدخلات المستخدم) .
قم بتشغيل لعبتك بأعلى إعداد جودة لمعرفة الأجهزة التي يمكنها دعمها.
قم بإجراء اختبار تقني ، مثل تجميع عدة تظليلات وتنفيذها والتحقق من أن الناتج كما هو متوقع.
الخطوة 1: قم بتسجيل مخطط URL المخصص الخاص بـ Test Lab
أولاً ، يجب عليك تسجيل مخطط عنوان URL المخصص لـ Firebase 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 (اختياري): تكوين التطبيق الخاص بك لتشغيل حلقات متعددة
إذا كان تطبيقك يحتوي على عدة مخططات عناوين URL مخصصة مسجلة وكنت تخطط لتشغيل حلقات متعددة (تعرف أيضًا بالسيناريوهات) في الاختبار ، فيجب عليك تحديد الحلقات التي تريد تشغيلها في تطبيقك في وقت التشغيل.
في مفوض التطبيق الخاص بك ، تجاوز 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).
}
}
}
الخطوة 3: إنشاء اختبار وتشغيله
بعد تسجيل مخطط عنوان URL المخصص لـ Test Lab ، يمكنك تشغيل اختبارك في وحدة تحكم Firebase أو باستخدام gcloud beta CLI . إذا لم تكن قد قمت بذلك بالفعل ، فقم بإنشاء ملف IPA لتطبيقك (ستحتاج إلى تحديد موقعه لاحقًا).
قم بإجراء اختبار في وحدة تحكم Firebase
إذا لم تكن قد قمت بذلك بالفعل ، فافتح وحدة تحكم Firebase وأنشئ مشروعًا.
في صفحة Test Lab بوحدة تحكم Firebase ، انقر فوق تشغيل الاختبار الأول> تشغيل حلقة لعبة iOS .
في قسم تحميل التطبيق ، انقر على تصفح ، ثم حدد ملف IPA الخاص بالتطبيق (إذا لم تكن قد قمت بذلك بالفعل ، فقم بإنشاء ملف IPA لتطبيقك).
اختياري : إذا كنت تريد تشغيل حلقات متعددة (ويعرف أيضًا باسم سيناريوهات) في وقت واحد أو تحديد حلقات معينة للتشغيل ، فأدخل أرقام الحلقة في حقل السيناريوهات .
على سبيل المثال ، عند إدخال "1-3 و 5" ، يقوم Test Lab بتشغيل الحلقات 1 و 2 و 3 و 5. بشكل افتراضي (إذا لم تقم بإدخال أي شيء في حقل السيناريوهات ) ، يقوم Test Lab بتشغيل الحلقة 1 فقط.
في قسم الأجهزة ، حدد جهازًا ماديًا واحدًا أو أكثر تريد اختبار تطبيقك عليه ، ثم انقر فوق بدء الاختبارات .
قم بإجراء اختبار باستخدام gcloud beta CLI
إذا لم تكن قد قمت بذلك بالفعل ، فقم بتهيئة بيئة gcloud SDK المحلية ، ثم تأكد من تثبيت مكون gcloud beta .
قم بتشغيل الأمر
gcloud beta firebase test ios run
واستخدم العلامات التالية لتهيئة التشغيل:
علامات اختبارات Game Loop | |
---|---|
--type | مطلوب : يحدد نوع اختبار iOS الذي تريد تشغيله. يمكنك إدخال أنواع الاختبار |
--app | مطلوب : المسار المطلق (Google Cloud Storage أو نظام الملفات) إلى ملف IPA الخاص بتطبيقك. هذه العلامة صالحة فقط عند إجراء اختبارات Game Loop. |
--scenario-numbers | الحلقات (المعروفة أيضًا بالسيناريوهات) التي تريد تشغيلها في تطبيقك. يمكنك إدخال حلقة واحدة ، أو قائمة أو حلقات ، أو نطاق من الحلقات. الحلقة الافتراضية هي 1. على سبيل المثال ، |
--device-model | الجهاز الفعلي الذي تريد إجراء اختبارك عليه (اكتشف الأجهزة المتاحة التي يمكنك استخدامها). |
--timeout | المدة القصوى التي تريد تشغيل اختبارك فيها. يمكنك إدخال عدد صحيح لتمثيل المدة بالثواني ، أو عدد صحيح وتعداد لتمثيل المدة كوحدة زمنية أطول. فمثلا:
|
على سبيل المثال ، يقوم الأمر التالي بتشغيل اختبار Game Loop الذي ينفذ الحلقات 1 و 4 و 6 و 7 و 8 على iPhone 8 Plus:
gcloud beta firebase test ios run --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8 --device-model=iphone8plus
لمزيد من المعلومات حول gcloud CLI ، راجع الوثائق المرجعية .
قم بإجراء اختبار محليًا
لإجراء الاختبار محليًا ، قم بتحميل تطبيق الألعاب الخاص بك في جهاز محاكاة وقم بتشغيل:
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
أنهِ الاختبار مبكرًا
بشكل افتراضي ، يستمر اختبار Game Loop في العمل حتى يصل إلى مهلة خمس دقائق ، حتى عندما يتم تنفيذ جميع الحلقات. عند الوصول إلى المهلة ، ينتهي الاختبار ويلغي أي حلقات معلقة. يمكنك تسريع اختبارك أو إنهائه مبكرًا عن طريق استدعاء مخطط عنوان URL المخصص الخاص بـ Test Lab's firebase-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 الحلقة الحالية وينفذ الحلقة التالية. عندما لا يكون هناك المزيد من الحلقات للتشغيل ، ينتهي الاختبار.
اكتب نتائج الاختبار المخصصة
يمكنك تكوين اختبار 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]; } }