يستخدم LogoRRR مكتبة TestFX لتشغيل اختبارات التكامل على واجهة مستخدم JavaFX الخاصة به. تمنح هذه الاختبارات الثقة بأن سير العمل الأساسي يصمد أمام الميزات الجديدة، وعمليات إعادة الهيكلة، وتحديثات التبعيات — كما تكتشف التراجعات التي لا تستطيع اختبارات الوحدة رؤيتها ببساطة.
لماذا الآن
بعد أكثر من 20 إصدارًا، أصبح LogoRRR معقدًا بما يكفي لأن الاختبار اليدوي وحده لم يعد كافيًا. احتاجت قاعدة الكود إلى شبكة أمان. تتيح مكتبة TestFX إمكانية التحكم في نافذة التطبيق الفعلية — النقر على الأزرار، وفتح الملفات، وفحص حالة واجهة المستخدم — من خلال طرق اختبار JUnit.
قرار متى تستثمر في اختبارات شاملة هو دائمًا مفاضلة. في وقت مبكر من المشروع، تتغير واجهات المستخدم بسرعة كبيرة تجعل مواكبة الاختبارات لها أمرًا صعبًا. لكن بمجرد استقرار التدفقات الأساسية، تصبح الاختبارات محركًا للتسريع بدلاً من أن تكون عبئًا. وصلت نقطة التحول هذه مع الإصدار 24.3.0.
التنفيذ
يُناسب البناء الجملي الموجز لـ Scala بطبيعته بناء DSL اختبار صغير. كل إجراء ذري — فتح ملف، والنقر على زر الإغلاق، والتأكد من أن جزء علامات التبويب فارغ — يصبح لبنة بناء مقروءة:
@Test def openAndCloseTab(): Unit = {
checkForEmptyTabPane()
openFile(path)
checkForNonEmptyTabPane()
clickOn(lookup(UiNodes.LogFileHeaderTabs).query[StackPane](), MouseButton.SECONDARY)
waitAndClickVisibleItem(CloseTabMenuItem.uiNode(fileId))
checkForEmptyTabPane()
}
أجبر كتابة اختبارات الواجهة الأمامية على إجراء تحسينات على كود الإنتاج أيضًا. تمت إضافة طبقة Service جديدة لتجريد عمليات I/O للملفات واستدعاءات العمليات الخارجية — وهي تغييرات حسّنت البنية بشكل مستقل عن أي فائدة للاختبار.
ما اكتشفته الاختبارات
- سلوك إيقاف تشغيل التطبيق — أصبحت الموارد التي لم يُنظَّف بعدها بشكل صحيح واضحة تحت الاختبار
- عزل الاختبار — يجب أن يُعدّ كل اختبار حالته الخاصة ويُزيلها، مما كشف عن عدة افتراضات دقيقة حول حالة واجهة المستخدم المشتركة
- خط الأداء الأساسي — مراقبة وقت تنفيذ الاختبار تمنع التراكم البطيء للاختبارات البطيئة
صورة الغلاف بواسطة Sora Shimazaki على Pexels.
