Detox هو إطار عمل لاختبارات E2E من نوع gray-box لتطبيقات الهاتف المحمول، تم إنشاؤه بواسطة فريق Wix خصيصاً لمشاريع React Native. على عكس نهج black-box، يتمتع Detox بإمكانية الوصول إلى الحالة الداخلية للتطبيق، مما يسمح بالمزامنة التلقائية دون مهلات زمنية يدوية. وفقاً لـ Wix Engineering, 2026، فإن المزامنة التلقائية تقلل وقت تشغيل الاختبارات بنسبة 40% مقارنة بالتوقفات التقليدية.
الرئيسية
Detox هو إطار عمل لاختبارات النهاية إلى النهاية (E2E) لتطبيقات الهاتف المحمول، تم تطويره بواسطة Wix في عام 2017. وهو مصمم لمشاريع React Native ولكنه يدعم أيضاً التطبيقات الأصلية على iOS وAndroid. يعمل Detox بنموذج gray-box، مما يعني أنه لديه إمكانية الوصول إلى الآليات الداخلية للتطبيق.
الفرق الرئيسي بين Detox و Appium أو Calabash هو المزامنة التلقائية مع التطبيق. ينتظر الإطار اكتمال الرسوم المتحركة وطلبات الشبكة ومعالجة الأحداث قبل تنفيذ الإجراء التالي. هذا يلغي تماماً الحاجة إلى Thread.sleep() أو waitForElement التي تبطئ الاختبارات.
يدعم Detox iOS (عبر XCTest و Xcode) و Android (عبر Espresso و UI Automator). لتطبيقات React Native، يتم توفير دعم كامل لـ Fabric والهندسة القديمة. على iOS، تُجرى الاختبارات على المحاكي؛ على Android، على المحاكي أو جهاز حقيقي.
تتكون هندسة Detox من ثلاثة مكونات رئيسية: Detox CLI، ومشغل اختبارات Detox، وبرنامج التشغيل الأصلي Detox Native Driver. Detox CLI يدير بناء التطبيق وتثبيته وتنفيذ الاختبارات. يقوم مشغل الاختبارات (Jest أو Mocha) بتنفيذ سيناريوهات الاختبار والتواصل مع التطبيق عبر WebSocket.
اختبار gray-box يعني أن Detox لديه إمكانية الوصول إلى الحالة الداخلية للتطبيق من خلال جسر أصلي. يراقب الإطار طلبات الشبكة والرسوم المتحركة والمؤقتات وقائمة العمليات. عندما تكون جميع قوائم الانتظار فارغة، يعتبر Detox التطبيق جاهزاً للخطوة التالية.
تعتمد المزامنة على مراقبة الخيط الرئيسي للتطبيق. ينتظر Detox حتى تكتمل جميع الرسوم المتحركة وتعود طلبات HTTP بالاستجابات وتنتهي معالجات الأحداث من التنفيذ. إذا توقف اختبار بسبب رسوم متحركة لا نهائية، يمكن تعطيل المزامنة يدوياً لكتلة كود محددة.
// تعطيل المزامنة لقسم مشكلة
await device.disableSynchronization();
// إجراء مع رسوم متحركة طويلة
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
يبدأ تثبيت Detox بإضافة الحزمة عبر npm أو yarn. بعد التثبيت، تحتاج إلى إنشاء ملف تكوين .detoxrc.js، الذي يصف إعدادات البناء والتشغيل لكل منصة. يستخدم Detox نوع البناء الخاص به لنظام iOS، بناءً على تكوين Xcode.
يتضمن التكوين المسار إلى التطبيق (app)، ونوع البناء (build)، ووسائط البناء وإعدادات الجهاز (device). لنظام iOS، يُستخدم appleSimulator، ولنظام Android androidEmulator. يمكنك أيضاً تحديد وسائط التشغيل مثل لغة أو منطقة المحاكي.
// .detoxrc.js — مثال تكوين
module.exports = {
testRunner: { args: { '$0': 'jest', config: 'e2e/config.json' } },
apps: {
'ios.debug': { type: 'ios.app', build: 'xcodebuild ...' },
'android.debug': { type: 'android.apk', build: 'cd android && ./gradlew ...' }
},
devices: {
simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } },
emulator: { type: 'android.emulator', device: { avdName: 'Pixel_4_API_34' } }
}
};
بعد التكوين، تتوفر الأوامر التالية: detox build — يبني التطبيق مع أعلام الاختبار، و detox test — يشغل الاختبارات. يدعم Detox التنفيذ المتوازي على أجهزة متعددة باستخدام العلم --workers.
تُكتب اختبارات Detox بلغة JavaScript أو TypeScript باستخدام واجهة برمجة تطبيقات تعتمد على البحث عن العناصر (matchers) والإجراءات (actions). تسمح matchers بالعثور على عنصر بواسطة المعرف أو النص أو النوع أو الموضع على الشاشة. تنفذ الإجراءات النقر وإدخال النص والتمرير السريع والتمرير.
يتبع الاختبار النموذجي هذا التسلسل: العثور على عنصر → تنفيذ إجراء → التحقق من النتيجة. للتحقق، تُستخدم واجهة برمجة التطبيقات expect مع matchers للوجود أو الرؤية أو نص العنصر. يدعم Detox صياغة describe/it من خلال التكامل مع Jest.
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should log in with valid credentials', async () => {
await element(by.id('emailInput')).typeText('user@test.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.id('homeScreen'))).toBeVisible();
});
});
يدعم Detox جميع الإيماءات الشائعة: tap، longPress، swipe، scroll، pinch، multiTap. لـ scroll يمكنك تحديد الاتجاه والسرعة وموضع التوقف. هذا يسمح باختبار سيناريوهات معقدة مثل pull-to-refresh أو الدوارات.
يتكامل Detox جيداً مع أنظمة CI الشهيرة: GitHub Actions و CircleCI و Bitrise و Jenkins. للتشغيل في CI، تحتاج إلى إعداد محاكي iOS افتراضي (بدون واجهة رسومية) ومحاكي Android مع تسريع أجهزة. يوفر Detox القطع الأثرية — لقطات الشاشة والسجلات — لتحليل الاختبارات الفاشلة.
لتسريع تشغيل الاختبارات في CI، يُوصى باستخدام التقسيم (المعالجة المتوازية) مع العلم --workers. يوزع Detox تلقائياً ملفات الاختبار عبر محاكيات متعددة. من المفيد أيضاً تخزين بناءات التطبيق مؤقتاً بين مرات التشغيل لتقليل وقت البناء.
# GitHub Actions — تشغيل Detox على iOS
- name: Install Dependencies
run: npm ci
- name: Build Detox App
run: npx detox build --configuration ios.sim
- name: Run Detox Tests
run: npx detox test --configuration ios.sim --workers 2
timeout-minutes: 30
لاختبارات E2E مستقرة وسريعة، يُوصى باتباع عدة قواعد. تجنب sleep() — يوفر Detox مزامنة تلقائية، والتأخيرات الصريحة فقط تبطئ الاختبارات وتجعلها غير مستقرة. إذا فشل اختبار بسبب مشاكل توقيت، تحقق أولاً مما إذا كانت المزامنة معطلة. من المفيد أيضاً تجميع الاختبارات حسب الميزة وتشغيلها بشكل مستقل — هذا يبسط البحث عن سبب الفشل.
يوفر Detox عدة طرق لـ device لإدارة الحالة: device.reloadReactNative() يعيد تحميل الحزمة، device.launchNewApp() يشغل التطبيق بمعلمات جديدة، device.sendToHome() يصغر التطبيق. device.setURLBlacklist() يسمح باستبعاد عناوين URL معينة من المزامنة، وهو مفيد للتحليلات واتصالات long-polling.
لكل اختبار، يُوصى بإنشاء حالة معزولة. استخدم beforeEach لإعادة تحميل التطبيق عبر device.reloadReactNative(). للاختبارات التي تتطلب بيانات محددة، أنشئ مصانع أو عملاء API لإعداد البيانات على الخادم. تجنب التبعيات بين الاختبارات — يجب أن يكون كل اختبار مستقلاً.
يدعم Detox اختبار WebView عبر طريقتي web.element() و web.invoke(). للتفاعل مع العناصر web، يُستخدم by.web](:id أو css أو className. من المهم تذكر أن WebView يتطلب وقت تحميل إضافي — إذا لم تعمل المزامنة، أضف انتظار تحميل باستخدام waitFor.
// اختبار WebView في Detox
const webView = web(by.id('webview'));
await webView.element(by.web.cssSelector('#submit-btn')).tap();
const result = await webView.element(
by.web.cssSelector('.result-text')
).getText();
await expect(result).toEqual('Success');
يدعم Detox مقارنة لقطات الشاشة عبر إضافة detox-image-matching. تسمح لقطات الشاشة باكتشاف الانحدارات البصرية: العناصر المنزاحة، الألوان غير الصحيحة، الأيقونات المفقودة. للحصول على لقطات مستقرة، عطل الرسوم المتحركة واستخدم حجماً ثابتاً للمحاكي.
أكثر مشاكل Detox شيوعاً تتعلق بالمزامنة: رسوم متحركة لا نهائية، طلبات شبكة طويلة أو مؤقتات عالقة. التسجيل مع العلم --loglevel trace يظهر الموارد التي ينتظرها Detox. إذا توقف Detox، استخدم device.disableSynchronization() لكتلة الكود المشكلة.
على محاكي iOS، يتطلب Detox بناء التطبيق أولاً عبر xcodebuild مع تكوين iphonesimulator. خطأ شائع هو استخدام مخطط Release بدلاً من Debug، مما يعطل أعلام الاختبار. لنظام Android، تأكد من إنشاء AVD بواجهة برمجة متوافقة مع تطبيقك وتمكين تسريع Intel HAXM. لبيئات CI على macOS، من المناسب استخدام GitHub Actions مع مشغل macOS، حيث Xcode والمحاكيات مثبتة مسبقاً.
إذا فشلت الاختبارات بانتظام بسبب المهلة، تحقق: هل المزامنة معطلة عالمياً، هل تُستخدم setTimeout أو setInterval في كود التطبيق دون تنظيف، وهل الخيط الرئيسي محظور بعملية طويلة. أحياناً يساعد زيادة المهلة في detoxrc.js عبر testRunner.args.jest.$.testTimeout. للعثور على المناطق المشكلة، فعّل تسجيل التتبع لـ Detox — يظهر الموارد والمؤقتات التي ينتظرها الإطار حالياً.
بعد تشغيل الاختبارات، ينشئ Detox قطعاً أثرية: لقطات شاشة للاختبارات الفاشلة، وسجلات التطبيق وتقارير JUnit XML. تُلتقط لقطات الشاشة تلقائياً عند فشل الاختبار وتساعد في تحديد المشكلة بصرياً. لـ CI، تُرفع القطع الأثرية إلى التخزين السحابي وتكون متاحة عبر واجهة ويب لتحليل أسباب الفشل.
الأسئلة الشائعة
يستخدم Detox نهج gray-box مع الوصول إلى الحالة الداخلية للتطبيق والمزامنة التلقائية. يعمل Appium بنموذج black-box عبر WebDriver ويتطلب انتظارات يدوية. Detox أسرع وأكثر استقراراً لمشاريع React Native.
تُكتب اختبارات Detox بلغة JavaScript أو TypeScript. يتكامل الإطار مع Jest و Mocha كمشغلات اختبار. المحرك الأصلي لنظام iOS مكتوب بلغة Swift، ولنظام Android بلغتي Kotlin و Java.
نعم، يدعم Detox التطبيقات الأصلية على iOS (عبر XCTest) و Android (عبر Espresso). ومع ذلك، الجمهور الرئيسي لـ Detox هم مطورو React Native، نظراً لوجود حلول أكثر نضجاً للمشاريع الأصلية.
يوفر Detox قطعاً أثرية: لقطات شاشة وسجلات التطبيق وتقارير HTML. للتصحيح المحلي، استخدم العلم --loglevel trace، ولـ CI، جامع قطع أثرية تلقائي مع الرفع إلى السحابة.
هذه طريقة من واجهة برمجة Detox تعيد تحميل حزمة JavaScript الخاصة بـ React Native دون إعادة تثبيت التطبيق. تُستخدم في beforeEach لإعادة تعيين حالة التطبيق إلى الشاشة الأولية قبل كل اختبار.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا