> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# أفكار مشاريع تخرج في هندسة البرمجيات Software Engineering
- URL: https://arabroot.io/articles/افكار-مشاريع-تخرج-في-هندسة-البرمجيات-للبكالوريوس-والماجستير/
- Published: 2026-11-01T18:47:03.000Z
- Updated: 2026-11-01T19:57:13.000Z
- Description: خمس عشرة فكرة لمشروع تخرج أو رسالة ماجستير في هندسة البرمجيات، لكل فكرة بيانات حقيقية وطريقة تقييم والخطر الذي يقتلها، مع تجربة جدوى على بيانات الاختبارات المتقلبة.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, للطلاب والخريجين

انتهى أول اجتماع مع المشرف، وقبل أن تخرجوا من مكتبه قال لكم جملة واحدة: «أحضروا ثلاث أفكار الأسبوع القادم، ولكل فكرة صفحة واحدة: المشكلة، ومن سيستخدم النظام، وكيف ستعرفون أنكم نجحتم». فجلست أنت وثلاثة من زملائك في هندسة البرمجيات وفتحتم قائمة مشاريع الدفعات السابقة التي نشرها القسم، فوجدتم فيها نظام حضور بالبصمة، ونظام حضور بالوجه، ومتجراً إلكترونياً للعطور، وتطبيق حجز مواعيد لعيادة، وروبوت محادثة «يجيب عن أسئلة الطلاب». وكل واحد منكم يعرف في داخله أن المشرف رأى هذه الأفكار عشرات المرات، وأن اللجنة سوف تسأل في المناقشة: ما الجديد هنا؟ ولكن لا أحد منكم يعرف بالضبط من أين يأتي بفكرة أفضل، ولا كيف يعرف قبل أن يبدأ أن الفكرة ممكنة في فصلين دراسيين.

ومشكلة طالب هندسة البرمجيات بالذات أن تخصصه ليس «بناء تطبيق»، فصديقك في علوم الحاسب يمكن أن يقدم خوارزمية أسرع، وصديقك في تقنية المعلومات يمكن أن يقدم بنية تشغيل، أما أنت فالمنتظر منك أن تقدم نظاماً بني بطريقة هندسية: متطلبات مكتوبة ومتتبعة، ومعمارية لها قرارات موثقة، واختبارات تقيس شيئاً حقيقياً، وتقييم يثبت أن النظام يحل المشكلة. وقد شرحنا في [دليل تخصص هندسة البرمجيات](https://arabroot.io/articles/%D8%AA%D8%AE%D8%B5%D8%B5-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84-%D9%85%D9%86%D9%87%D8%AC-se2014/) أن منهج SE2014 يطلب من مشروع التخرج Capstone أن يمتد سنة كاملة، وأن يكون جماعياً، وأن ينتهي بتنفيذ فعلي، وأن يقيم بأكثر من «بنيناه واشتغل»، ويفضل أن يكون له عميل غير المشرف. وهذا المقال يأخذ هذه الشروط ويحولها إلى أفكار محددة، لكل فكرة بطاقة تقول لك ما تحتاجه لتبدأ، وهو من مرحلة [مشروع التخرج للبكالوريوس والماجستير](https://arabroot.io/start/#stage-grad-projects) في مسار الطلاب والخريجين.

وسوف نناقش في هذا المقال ما يلي:

- ما الذي يجعل مشروع هندسة البرمجيات مختلفاً عن مشروع البرمجة، وما الذي تطلبه اللجنة من البكالوريوس ومن الماجستير.
- كيف تقرأ بطاقة الفكرة: المشكلة، والمستخدم، والنطاق، والتقنيات، ومصادر البيانات، والتقييم، والصعوبة، والخطر الذي يقتل الفكرة، وكيف تتميز.
- تسع أفكار للبكالوريوس: أدوات الواجهات العربية وسهولة الوصول، وتتبع المتطلبات، وخدمات حكومية ومالية بمعمارية صحيحة، والمساهمة في المصادر المفتوحة، وقياس أداء الفريق.
- ست أفكار للماجستير في جودة البرمجيات: الاختبارات المتقلبة، واختبار الطفرات، والاختبار القائم على الخصائص للنص العربي، والدين التقني، واختبار العقود، وعيوب المتطلبات العربية.
- الأفكار المستهلكة التي ملها المشرفون، وكيف تحول واحدة منها إلى مشروع حقيقي.
- جدول مقارنة لكل الأفكار.
- تجربة عملية Lab: تجربة جدوى Feasibility Spike على بيانات حقيقية للاختبارات المتقلبة، والمشكلات التي ظهرت فيها، وماذا يحدث إذا غيرنا طريقة تقسيم البيانات.
- أخطاء شائعة، وقائمة تحقق قبل أن تقدم المقترح.

## ما الذي يجعل مشروع هندسة البرمجيات Software Engineering مختلفاً؟

لنأخذ نفس الفكرة ونعطيها لفريقين. الفريق الأول يبني تطبيق حجز مواعيد، فيفتح المحرر في الأسبوع الأول، ويرسم الشاشات وهو يبرمجها، وفي آخر الفصل الثاني يعرض التطبيق وهو يعمل على جهاز واحد، وإذا سألته اللجنة «كيف عرفتم أن النظام صحيح؟» قال «جربناه». والفريق الثاني يبني نفس التطبيق، ولكنه يبدأ بمقابلة ثلاث عيادات ويكتب منها متطلبات مرقمة، ويرسم المعمارية ويكتب لكل قرار مهم سجلاً قصيراً يشرح لماذا اختاره، ويربط كل متطلب بالاختبار الذي يتحقق منه، ويقيس في النهاية زمن الحجز ونسبة الأخطاء مع مستخدمين حقيقيين. كلا الفريقين بنى تطبيقاً، ولكن الثاني فقط قدم مشروع هندسة برمجيات، والسبب أن الناتج في هذا التخصص ليس الكود وحده، وإنما الكود ومعه الدليل على أنه صحيح ومناسب وقابل للصيانة.

وهذا الفرق هو ما يجعل الفكرة نفسها أقل أهمية مما يظن الطلاب، فالمشرف لا يمل من «تطبيق المواعيد» لأنه تطبيق مواعيد، وإنما لأن أغلب من قدموه لم يقيسوا شيئاً ولم يواجهوا مشكلة هندسية حقيقية. لذلك سوف تجد أن كل فكرة في هذا المقال فيها جزء صعب مقصود: بيانات حقيقية غير نظيفة، أو مستخدم حقيقي له متطلبات متضاربة، أو معيار خارجي يجب أن يلتزم به النظام مثل معيار الفوترة الإلكترونية أو معيار سهولة الوصول، أو مشروع مفتوح المصدر يراجع فيه غرباء كودك. وهذا الجزء الصعب هو ما ستتحدث عنه في المناقشة، وهو ما يجعل المشروع سطراً له معنى في سيرتك الذاتية.

وقد يتساءل البعض: هل يعني هذا أن مشروع هندسة البرمجيات يجب أن يكون أداة للمطورين؟ والإجابة لا، فنصف الأفكار التالية تطبيقات لمستخدمين عاديين، مثل بوابة بلاغات بلدية أو تطبيق لمجموعات المعتمرين، ولكن الفرق أن الطريقة التي تبنيها بها هي موضوع المشروع بقدر ما هو التطبيق نفسه، والنصف الآخر أدوات تساعد الفرق على الجودة، وهي أسهل في التقييم لأن نتيجتها رقم يمكن قياسه، مثل عدد الأخطاء التي اكتشفتها الأداة أو الوقت الذي وفرته.

## البكالوريوس Bachelor مقابل الماجستير Master: ماذا تطلب اللجنة؟

مشروع البكالوريوس في أغلب الجامعات السعودية فريق من ثلاثة إلى خمسة طلاب على فصلين دراسيين، في الفصل الأول المتطلبات والتصميم ونموذج أولي Prototype، وفي الثاني التنفيذ والاختبار والتقييم، والسؤال الذي تجيب عنه اللجنة: هل بنى الفريق نظاماً يعمل، بطريقة هندسية، ويحل مشكلة حقيقية؟ لذلك فالجديد Novelty في البكالوريوس ليس شرطاً بالمعنى البحثي، ويكفي أن يكون المشروع مفيداً وغير مكرر وأن يكون فيه تقييم صادق. أما رسالة الماجستير فهي عمل فرد واحد في الغالب، والسؤال فيها مختلف تماماً: ما سؤال البحث Research Question؟ وماذا فعل غيرك فيه، أي الأعمال السابقة Related Work؟ وما الذي تضيفه أنت ولم يفعله أحد؟ وكيف تقيس الإضافة بطريقة يستطيع غيرك أن يعيدها؟

الصورة التالية تبين الفرق بين المستويين في خمس نقاط، ولاحظ أن الماجستير لا يطلب نظاماً أكبر، بل قد يكون الكود فيه أصغر من مشروع البكالوريوس، ولكنه يطلب أن يكون كل رقم في الرسالة نتيجة تجربة مصممة، وأن يكون هناك خط أساس Baseline تقارن به.

![لوحة من عمودين: مشروع البكالوريوس لفريق من ثلاثة إلى خمسة طلاب على فصلين، ناتجه نظام يعمل مع متطلبات وتصميم واختبارات وتقييم مع مستخدمين، ورسالة الماجستير لطالب واحد، ناتجها سؤال بحث وأعمال سابقة وإضافة جديدة وتقييم قابل للإعادة مقابل خط أساس، وبينهما خمسة صفوف للمقارنة: الفريق والمدة والناتج والجديد والتقييم](https://arabroot.io/content/images/2026/11/grad-projects-se-01-bachelor-master.webp)

البكالوريوس يسأل هل يعمل النظام ويحل المشكلة، والماجستير يسأل ما الجديد وكيف قسته

وهناك خطأ يقع فيه طلاب الماجستير كثيراً، وهو أن يقدموا مشروع بكالوريوس كبيراً على أنه رسالة: «بنينا منصة لإدارة الاختبارات فيها عشرون شاشة». فتسأل اللجنة: ما سؤال البحث؟ فلا يجد الطالب إجابة، لأن المنصة أداة وليست سؤالاً. والحل أن تحول الأداة إلى وسيلة تجيب بها عن سؤال، مثل «هل تقلل هذه الطريقة في اختيار الاختبارات زمن التشغيل في CI بأكثر من 30% دون أن تفقد أكثر من 2% من الأخطاء المكتشفة؟»، فهنا أصبح للمنصة دور، وأصبح للرسالة رقم يقاس. وقد شرحنا كيف تجد الفجوة في الأدبيات في [دليل البحث في الأدبيات العلمية](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D8%AA%D8%AC%D8%AF-%D8%A7%D9%84%D9%81%D8%AC%D9%88%D8%A9-%D8%A7%D9%84%D8%A8%D8%AD%D8%AB%D9%8A%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%A7%D8%AF%D8%A8%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D9%85%D9%8A%D8%A9/)، وكيف تجعل تجربتك قابلة للإعادة في [دليل البحث القابل لإعادة الإنتاج](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84-%D9%84%D8%A7%D8%B9%D8%A7%D8%AF%D8%A9-%D8%A7%D9%84%D8%A7%D9%86%D8%AA%D8%A7%D8%AC-%D9%85%D8%B9-jupyter-%D9%88-git-%D9%88-docker/).

## كيف تقرأ بطاقة الفكرة Idea Card؟

كل فكرة في هذا المقال مكتوبة بنفس الشكل، حتى تقارن بينها بسرعة، وحتى تستطيع أن تنقل البطاقة كما هي إلى صفحة المقترح التي طلبها المشرف. وفيما يلي معنى كل حقل:

- المشكلة Problem: ما الذي يحدث اليوم ولا يعمل، بكلمات يفهمها شخص خارج القسم.
- المستخدم Users: من سيستخدم النظام فعلاً، وهذا الحقل هو الذي يحدد من تقابل في الفصل الأول.
- النطاق Scope: ما الذي يبنيه فريق من ثلاثة إلى خمسة في فصلين، وما الذي يجب أن تتركه خارج المشروع.
- التقنيات Stack: اقتراح وليس إلزاماً، والمهم أن يكون فيه ما يمكن اختباره وقياسه.
- البيانات Data: مصدر حقيقي يمكنك أن تفتحه اليوم، وقد تحققنا من أن كل رابط في البطاقات يفتح.
- التقييم Evaluation: كيف تعرف أنك نجحت، بمقياس Metric أو دراسة مستخدمين User Study أو مقارنة بمعيار Benchmark.
- الصعوبة Difficulty: متوسطة أو عالية أو عالية جداً، بالنسبة لفريق في السنة الرابعة.
- الخطر الذي يقتلها Killer Risk: الشيء الذي إذا حدث في منتصف المشروع توقف كل شيء، ويجب أن تختبره في أول أسبوعين.
- كيف تتميز Stand Out: الإضافة الصغيرة التي تنقل المشروع من «مقبول» إلى «ممتاز».

وأهم حقل في البطاقة هو الخطر الذي يقتل الفكرة، لأن أغلب مشاريع التخرج لا تفشل بسبب الكود، وإنما بسبب شيء خارجي اكتشفه الفريق متأخراً: بيانات لم تصل، أو جهة وعدت بالتعاون ثم انشغلت، أو واجهة برمجية API تحتاج ترخيصاً لا يعطى للطلاب. لذلك سوف نختم المقال بتجربة جدوى Feasibility Spike على إحدى أفكار الماجستير، حتى ترى كيف تختبر الخطر في يومين قبل أن تلتزم به في سنة.

والصورة التالية تضع الأفكار الخمس عشرة في خمس مجموعات، وتبين لكل فكرة مستواها، حتى ترى أين تقع الفكرة التي تميل لها بين الباقي.

![خريطة من خمس مجموعات للأفكار: الواجهات العربية وسهولة الوصول وفيها مدقق RTL ومراقب Accessibility واختبار الخصائص للنص العربي، والمتطلبات وفيها تتبع المتطلبات وعيوب المتطلبات العربية، والاختبار والجودة وفيها الاختبارات المتقلبة واختبار الطفرات واختبار العقود والدين التقني، والأنظمة الحقيقية وفيها بلاغات البلدية Open311 وتقسيم المصروفات مع Open Banking والفوترة ZATCA وتطبيق مجموعات الحج والعمرة، والفريق والمصادر المفتوحة وفيها المساهمة في مشروع مفتوح ولوحة DORA، ولكل فكرة شارة بكالوريوس أو ماجستير](https://arabroot.io/content/images/2026/11/grad-projects-se-02-ideas-map.webp)

خمس عشرة فكرة في خمس مجموعات، تسع للبكالوريوس وست للماجستير

## أفكار مشاريع البكالوريوس Bachelor Projects

الأفكار التسع التالية مكتوبة لفريق من ثلاثة إلى خمسة طلاب على فصلين، وفي كل واحدة نظام يعمل في النهاية، ومستخدم حقيقي، وتقييم يمكن قياسه. ورتبناها من الأقرب إلى أدوات المطورين إلى الأقرب إلى المستخدم العادي.

### مدقق الواجهات العربية RTL Linter لتطبيقات الويب

**Project title:** RTL Linter for Arabic Web Interfaces

كل من بنى واجهة عربية يعرف المشهد: السهم في زر «التالي» يشير إلى الاتجاه الخطأ، ورقم الجوال ينقلب ترتيبه عندما يأتي بعد كلمة عربية، والهامش الذي كتبه المطور بـ margin-left يظهر في الجهة الخطأ عند تحويل الصفحة إلى RTL. وهذه الأخطاء لا يكتشفها أي اختبار وحدة Unit Test، ولا يراها المطور الذي يعمل بواجهة إنجليزية، ويكتشفها المستخدم بعد الإطلاق. وقد شرحنا أسبابها في [دليل CSS للواجهات العربية](https://arabroot.io/articles/css-%D9%84%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9-%D8%A7%D9%84%D8%AE%D8%B5%D8%A7%D8%A6%D8%B5-%D8%A7%D9%84%D9%85%D9%86%D8%B7%D9%82%D9%8A%D8%A9-%D9%88-rtl/) وفي [دليل التعريب والنص ثنائي الاتجاه](https://arabroot.io/articles/%D8%A7%D9%84%D8%AA%D8%B9%D8%B1%D9%8A%D8%A8-i18n-%D9%88%D8%A7%D9%84%D9%86%D8%B5-%D8%AB%D9%86%D8%A7%D8%A6%D9%8A-%D8%A7%D9%84%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-bidi-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86/)، والمشروع هنا أن تحول هذه المعرفة إلى أداة تعمل في خط CI.

- المشكلة: أخطاء الاتجاه في الواجهات العربية تكتشف يدوياً وبعد الإطلاق، ولا توجد أداة مجانية تجمع فحص CSS وفحص النص المعروض في مكان واحد.
- المستخدم: فرق الواجهات في الشركات التي تبني تطبيقات عربية، وفريق القسم نفسه في مشاريعه القادمة.
- النطاق: قواعد لفحص ملفات CSS عبر [Stylelint](https://stylelint.io/?ref=arabroot.io) تكتشف الخصائص الفيزيائية Physical Properties مثل left وright وتقترح الخصائص المنطقية [Logical Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS%5Flogical%5Fproperties%5Fand%5Fvalues?ref=arabroot.io)، وفحص للصفحة المعروضة في متصفح بلا واجهة Headless Browser يكتشف غياب dir وlang ويكتشف النصوص المختلطة غير المعزولة، وتقرير يظهر في طلب الدمج Pull Request. واترك خارج المشروع الإصلاح التلقائي الكامل.
- التقنيات: Node.js، وStylelint، وPlaywright أو Puppeteer للمتصفح، وGitHub Actions أو Gitea Actions.
- البيانات: مستودعات مفتوحة المصدر فيها واجهات عربية، ومواصفة W3C [متطلبات تخطيط النص العربي Arabic Layout Requirements](https://www.w3.org/TR/alreq/?ref=arabroot.io)، و[خوارزمية الاتجاه الثنائي في Unicode](https://www.unicode.org/reports/tr9/?ref=arabroot.io) كمرجع لما هو صحيح.
- التقييم: اجمع عينة من عشرين مستودعاً، وافحص صفحاتها يدوياً لتصنع قائمة أخطاء مرجعية، ثم احسب الدقة Precision والاستدعاء Recall للأداة مقابلها، وأضف دراسة صغيرة: كم دقيقة يحتاج مطور ليجد نفس الأخطاء دون الأداة؟
- الصعوبة: متوسطة.
- الخطر الذي يقتلها: كثرة الإنذارات الكاذبة False Positives، فإذا أزعجت الأداة المطورين بعشرات التنبيهات غير المهمة أوقفوها. لذلك ابن القائمة المرجعية مبكراً وقس عليها كل قاعدة جديدة.
- كيف تتميز: افتح طلبات دمج حقيقية بالإصلاحات في ثلاثة مشاريع مفتوحة المصدر، فإذا قبل واحد منها فهذا دليل لا تجادل فيه اللجنة.

### مراقب سهولة الوصول Accessibility للخدمات الحكومية الرقمية

**Project title:** Accessibility Monitor for Government Digital Services

سهولة الوصول Accessibility تعني أن يستخدم موقعك من يقرأ الشاشة بقارئ الشاشة Screen Reader، ومن يتنقل بلوحة المفاتيح فقط، ومن يكبر الخط إلى 200%، وقد شرحنا أساسها في [دليل سهولة الوصول](https://arabroot.io/articles/%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%83%D9%8A%D9%81-%D8%AA%D8%A8%D9%86%D9%8A-%D9%85%D9%88%D9%82%D8%B9%D8%A7-%D9%8A%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D9%87-%D8%A7%D9%84%D8%AC%D9%85%D9%8A%D8%B9/) وأدوات فحصها على موقع عربي في [دليل اختبار سهولة الوصول](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%84%D9%85%D9%88%D9%82%D8%B9-%D8%B9%D8%B1%D8%A8%D9%8A/)، ومن أهم ما ظهر هناك أن الأدوات الآلية لا تفحص بعض الأشياء في النص العربي أصلاً. والمشروع أن تبني منصة تراقب صفحات عامة بشكل دوري، وتحفظ النتائج عبر الزمن، وتبين للفريق المسؤول ما تغير بعد كل إطلاق.

- المشكلة: الفحص يتم مرة واحدة قبل الإطلاق ثم ينسى، وكل تحديث للواجهة قد يعيد مشكلة أصلحت.
- المستخدم: فرق تطوير المواقع في الجهات، والجهة التي تتابع جودة الخدمات الرقمية، والمستخدمون من ذوي الإعاقة الذين يمكن أن تشركهم في التقييم.
- النطاق: جدولة فحص يومي لقائمة صفحات بمحرك [axe-core](https://github.com/dequelabs/axe-core?ref=arabroot.io)، وتخزين النتائج، ولوحة تبين الاتجاه لكل صفحة، وفحوص إضافية خاصة بالعربية مثل اللغة المعلنة واتجاه الصفحة. واترك خارج المشروع أي فحص يحتاج تسجيل دخول.
- التقنيات: Node.js وPlaywright وaxe-core، وPostgreSQL لتخزين النتائج، وواجهة بسيطة.
- البيانات: الصفحات العامة للخدمات، ومعيار [WCAG 2.2](https://www.w3.org/TR/WCAG22/?ref=arabroot.io) كمرجع، و[هيئة الحكومة الرقمية](https://dga.gov.sa/?ref=arabroot.io) كجهة يمكن أن تسأل عن متطلباتها. ولا تنشر في التقرير اسم جهة مع عيوب موقعها دون إذنها، واكتف بأرقام مجمعة.
- التقييم: قارن نتائج الأداة بفحص يدوي على عشر صفحات، واحسب نسبة ما تكتشفه الأداة مما يكتشفه الفحص اليدوي، واطلب من اثنين من مستخدمي قارئ الشاشة أن ينفذا مهمة على صفحتين ودون الملاحظات.
- الصعوبة: متوسطة.
- الخطر الذي يقتلها: أن تحجب المواقع الفحص الآلي أو تغير بنيتها كل أسبوع، لذلك ابدأ بقائمة صغيرة ثابتة، وأضف مواقع مفتوحة المصدر تملك أنت نسخة منها.
- كيف تتميز: أضف قاعدة جديدة خاصة بالعربية إلى axe-core أو إلى أداة مفتوحة أخرى، واكتب لها اختبارات، وقدمها للمشروع.

### أداة تتبع المتطلبات Requirements Traceability من المتطلب إلى الاختبار

**Project title:** Requirements-to-Test Traceability Tool

كل مشروع تخرج يكتب وثيقة متطلبات SRS في الفصل الأول، ثم لا يفتحها أحد في الفصل الثاني، وفي المناقشة يسأل عضو اللجنة: «المتطلب رقم 14، أين اختبرتموه؟» فيبحث الفريق في الكود أمام اللجنة. والتتبع Traceability هو أن تعرف لكل متطلب من أين جاء، وأي كود ينفذه، وأي اختبار يتحقق منه، وقد شرحنا المتطلبات نفسها في [دليل هندسة المتطلبات](https://arabroot.io/articles/%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D8%AA%D8%B7%D9%84%D8%A8%D8%A7%D8%AA-requirements-engineering/) وفي [المثال العملي من فكرة غامضة إلى متطلبات واضحة](https://arabroot.io/articles/%D9%85%D9%86-%D9%81%D9%83%D8%B1%D8%A9-%D8%BA%D8%A7%D9%85%D8%B6%D8%A9-%D8%A7%D9%84%D9%89-%D9%85%D8%AA%D8%B7%D9%84%D8%A8%D8%A7%D8%AA-%D9%88%D8%A7%D8%B6%D8%AD%D8%A9-%D9%85%D8%AB%D8%A7%D9%84-%D8%B9%D9%85%D9%84%D9%8A/). والمشروع أن تبني أداة خفيفة تعيش داخل المستودع نفسه، لا نظاماً ثقيلاً يحتاج ترخيصاً.

- المشكلة: المتطلبات في ملف Word، والمهام في نظام المهام Issues، والاختبارات في الكود، ولا يوجد رابط بينها.
- المستخدم: فرق مشاريع التخرج نفسها، والفرق الصغيرة في الشركات التي تحتاج دليل تتبع للعميل أو للمدقق.
- النطاق: صيغة بسيطة للمتطلبات في ملفات Markdown أو YAML داخل المستودع، ووسم في رسائل الـ Commit وفي أسماء الاختبارات مثل REQ-14، وأداة تقرأ الثلاثة وتنتج مصفوفة التتبع وتفشل خط CI إذا وجد متطلب إلزامي بلا اختبار.
- التقنيات: Python أو Go، وواجهة Git، وواجهة GitHub أو Gitea البرمجية، وتقرير HTML.
- البيانات: مستودعاتكم أنتم، ومستودعات مفتوحة تستخدم وسوماً للمتطلبات، وصيغة [EARS](https://alistairmavin.com/ears/?ref=arabroot.io) لكتابة المتطلبات إذا أردتم صيغة منظمة.
- التقييم: طبق الأداة على مشاريع ثلاث فرق من دفعتكم في منتصف الفصل الثاني، واحسب نسبة المتطلبات المتتبعة قبل الأداة وبعدها، واسأل الفرق في استبيان قصير عن الوقت الذي وفرته.
- الصعوبة: متوسطة.
- الخطر الذي يقتلها: ألا يلتزم المطورون بالوسوم، فتبقى المصفوفة فارغة. والحل أن تجعل الأداة تقترح الوسم من اسم الفرع أو المهمة بدلاً من أن تطلبه.
- كيف تتميز: اربطها بإدارة حالات الاختبار في [Kiwi TCMS](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%AD%D8%A7%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D9%85%D8%B9-kiwi-tcms/) حتى تشمل الاختبارات اليدوية، وقدم مشروعك أنت كأول مثال على الأداة في المناقشة.

### بوابة بلاغات البلدية Open311 بمعمارية نظيفة Clean Architecture

**Project title:** Open311 Municipal Issue Reporting Portal with Clean Architecture

حفرة في الشارع، أو إنارة معطلة، أو حاوية نفايات ممتلئة: هذه بلاغات يرسلها الناس كل يوم، وتنتقل بين أكثر من فريق قبل أن تغلق. وهناك معيار مفتوح لهذا النوع من الخدمات اسمه [GeoReport v2](https://wiki.open311.org/GeoReport%5Fv2/?ref=arabroot.io) من مبادرة Open311، يعرف واجهة برمجية لعرض أنواع الخدمات وإرسال طلبات الخدمة Service Requests ومتابعتها. والمشروع ليس «تطبيق بلاغات» آخر، وإنما نظام يلتزم بمعيار منشور، ومعماريته مفصولة بحيث يمكن تغيير قاعدة البيانات أو واجهة الجوال دون أن يتغير منطق النظام، وهذا ما شرحناه في [دليل Clean Architecture وHexagonal](https://arabroot.io/articles/clean-architecture-%D9%88-hexagonal-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF%D9%8A%D8%A7%D8%AA/).

- المشكلة: البلاغ يصل عبر قنوات متعددة، ولا يعرف صاحبه ماذا حدث له، ولا تعرف الجهة أين يتأخر.
- المستخدم: الساكن الذي يرسل البلاغ، وموظف الفرز، وفريق الصيانة في الميدان.
- النطاق: واجهة GeoReport v2 كاملة، وتطبيق جوال أو ويب للإرسال مع الموقع والصورة، ولوحة للفرز والتوزيع، وحالات البلاغ ومهلة الاستجابة SLA. واترك خارج المشروع التكامل مع أنظمة حكومية حقيقية، واستبدله بمحاكي.
- التقنيات: Kotlin مع Spring أو TypeScript مع NestJS، وPostgreSQL مع PostGIS، وFlutter للجوال، واختبارات العقود للواجهة.
- البيانات: [منصة البيانات المفتوحة السعودية](https://od.data.gov.sa/Data/ar/dataset?ref=arabroot.io) لبيانات الأحياء والخدمات البلدية المنشورة، وقائمة الخوادم التي تطبق المعيار في موقع Open311 لتختبر توافقك مع تطبيقات موجودة.
- التقييم: اختبر التوافق بتشغيل تطبيق عميل Client مفتوح المصدر كتب للمعيار على خادمك دون تعديل، وقس زمن الاستجابة مع مئات الطلبات المتزامنة بأداة اختبار الأداء Load Testing، وأجر دراسة قابلية الاستخدام Usability مع عشرة مستخدمين بمقياس SUS.
- الصعوبة: متوسطة إلى عالية.
- الخطر الذي يقتلها: أن يتحول المشروع إلى شاشات كثيرة بلا عمق، لذلك حدد من البداية أن المعيار والمعمارية والاختبارات هي موضوع التقييم.
- كيف تتميز: وثق كل قرار معماري بسجل ADR ومخطط C4 كما في [دليل توثيق المعمارية](https://arabroot.io/articles/%D8%AA%D9%88%D8%AB%D9%8A%D9%82-%D8%A7%D9%84%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D9%85%D8%AE%D8%B7%D8%B7%D8%A7%D8%AA-c4-%D9%88-adr/)، واعرض في المناقشة كيف استبدلت قاعدة البيانات أو مزود الخرائط في يوم واحد.

### تطبيق تقسيم المصروفات مع المصرفية المفتوحة Open Banking

**Project title:** Expense Splitting App with Open Banking Integration

مجموعة من الأصدقاء يسكنون معاً، أو عائلة تتقاسم مصاريف سفر، وكل واحد يدفع شيئاً ثم يجلسون آخر الشهر مع ورقة وحاسبة. والتطبيقات الموجودة تطلب منك أن تدخل كل مصروف يدوياً، بينما المصرفية المفتوحة Open Banking تسمح، بموافقة العميل، بأن يقرأ تطبيق مرخص حركات حسابه. وقد شرحنا إطار البنك المركزي السعودي ومراحله في [دليل المصرفية المفتوحة](https://arabroot.io/articles/%D8%A7%D9%84%D9%85%D8%B5%D8%B1%D9%81%D9%8A%D8%A9-%D8%A7%D9%84%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-open-banking-%D8%A7%D8%B7%D8%A7%D8%B1-%D8%A7%D9%84%D8%A8%D9%86%D9%83-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A-%D9%88%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA/)، وذكرنا هناك أن الخدمات انتقلت من البيئة التجريبية التشريعية Regulatory Sandbox إلى مرحلة الترخيص، وهذا يعني أن مشروعك لن يتصل ببنك حقيقي، وإنما ببيئة اختبار، وهذا مقبول تماماً لمشروع تخرج إذا قلته بوضوح.

- المشكلة: تقسيم المصاريف المشتركة يدوي ويسبب خلافات، والبيانات موجودة أصلاً في الحسابات البنكية.
- المستخدم: الطلاب والعائلات والمجموعات الصغيرة.
- النطاق: ربط حساب عبر بيئة اختبار تحاكي واجهات معلومات الحساب، وتصنيف الحركات المشتركة، وقواعد تقسيم مرنة، وحساب التسوية بأقل عدد من التحويلات، وتصميم الموافقة Consent وسحبها كما يطلبه الإطار.
- التقنيات: Flutter أو React Native، وخادم بلغة Kotlin أو Go، و[Open Bank Project API](https://github.com/OpenBankProject/OBP-API?ref=arabroot.io) مفتوح المصدر كبيئة اختبار محلية تحاكي البنك.
- البيانات: حسابات وحركات وهمية في بيئة الاختبار، ووثائق إطار المصرفية المفتوحة من البنك المركزي كما ربطناها في الدليل.
- التقييم: اختبارات خصائص Property Tests تتأكد أن مجموع ما يدين به الجميع صفر دائماً، وقياس عدد التحويلات مقابل الطريقة البسيطة، ودراسة مستخدمين مع خمس مجموعات حقيقية تستخدم بيانات وهمية.
- الصعوبة: عالية.
- الخطر الذي يقتلها: أن يعتقد الفريق أنه يستطيع الاتصال ببنك حقيقي، فيضيع الفصل الأول في انتظار موافقة لن تأتي. والصحيح أن تبني على بيئة اختبار من اليوم الأول، وأن تصمم طبقة المزود Provider بحيث يمكن استبدالها لاحقاً.
- كيف تتميز: اكتب نموذج التهديدات Threat Model للموافقة والتوكن، واختبر أن سحب الموافقة يوقف القراءة فعلاً خلال ثوان.

### مكتبة الفوترة الإلكترونية ZATCA مفتوحة المصدر للمتاجر الصغيرة

**Project title:** Open Source ZATCA E-Invoicing Library for Small Merchants

الفوترة الإلكترونية في المملكة لها متطلبات تقنية محددة، من صيغة الفاتورة إلى رمز QR إلى الربط مع منصة الهيئة، وقد شرحنا كيف تربط نظامك بها في [دليل الفوترة الإلكترونية ZATCA](https://arabroot.io/articles/%D8%A7%D9%84%D9%81%D9%88%D8%AA%D8%B1%D8%A9-%D8%A7%D9%84%D8%A7%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A%D8%A9-%D9%81%D8%A7%D8%AA%D9%88%D8%B1%D8%A9-zatca-%D9%83%D9%8A%D9%81-%D8%AA%D8%B1%D8%A8%D8%B7-%D9%86%D8%B8%D8%A7%D9%85%D9%83/). والمتجر الصغير الذي يستخدم نظام نقاط بيع مفتوح المصدر أو نظاماً كتبه مطور مستقل يحتاج مكتبة موثوقة تقوم بهذا العمل، ومعظم ما يجده اليوم أكواد متفرقة دون اختبارات. والمشروع أن تبني هذه المكتبة كما تبنى المكتبات الجادة: واجهة واضحة، واختبارات مقابل المواصفة، وتوثيق، وإصدارات مرقمة.

- المشكلة: كل مطور يكتب نفس الكود من الصفر، ويكتشف الأخطاء عند رفض الفاتورة.
- المستخدم: مطورو أنظمة نقاط البيع والمتاجر الصغيرة، ومشاريع مفتوحة المصدر تحتاج دعم السوق السعودي.
- النطاق: إنشاء الفاتورة بالصيغة المطلوبة، وتوليد رمز QR، والتوقيع، والإرسال لبيئة الاختبار، ورسائل خطأ مفهومة بالعربية، ومثال تكامل مع نظام نقاط بيع مفتوح المصدر.
- التقنيات: Python أو TypeScript أو Java بحسب النظام الذي ستتكامل معه، واختبارات وحدة وتكامل، وتوثيق بالعربية والإنجليزية.
- البيانات: [بوابة المطورين وبيئة الاختبار](https://sandbox.zatca.gov.sa/?ref=arabroot.io) لدى الهيئة، و[صفحة الفوترة الإلكترونية](https://zatca.gov.sa/en/E-Invoicing/Pages/default.aspx?ref=arabroot.io) بوثائقها.
- التقييم: نسبة الفواتير التجريبية المقبولة من بيئة الاختبار في مجموعة حالات تغطي كل نوع فاتورة، وتغطية الاختبارات، وزمن تكامل مطور جديد مع المكتبة في تجربة مع ثلاثة مطورين.
- الصعوبة: عالية.
- الخطر الذي يقتلها: تغير المواصفة أو شروط الوصول لبيئة الاختبار، لذلك اقرأ الوثائق المنشورة في الأسبوع الأول وسجل في بيئة الاختبار قبل أن تكتب سطراً واحداً.
- كيف تتميز: انشرها بترخيص مفتوح واضح كما شرحنا في [دليل تراخيص المصادر المفتوحة](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%8A-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D9%88%D8%AA%D8%B1%D8%A7%D8%AE%D9%8A%D8%B5%D9%87%D8%A7/)، وقس عدد من استخدمها خارج الجامعة.

### تطبيق مجموعات الحج والعمرة دون اتصال Offline-First

**Project title:** Offline-First App for Hajj and Umrah Groups

قائد مجموعة من المعتمرين أو الحجاج يتابع خمسين شخصاً، ويرسل لهم مواعيد الحافلة وأماكن التجمع، والشبكة في أوقات الزحام قد تكون بطيئة جداً أو تنقطع. والتطبيق الذي يعتمد على الاتصال الدائم يتوقف في أكثر لحظة يحتاجه فيها الناس، أما تطبيق «دون اتصال أولاً» Offline-First فيعمل على بيانات محلية، ويرسل التغييرات عندما يعود الاتصال، ويحل التعارض إذا عدل شخصان نفس الشيء. وهنا الجزء الهندسي الحقيقي: كيف تصمم المزامنة Sync وكيف تختبرها، وقد شرحنا تخزين البيانات في المتصفح وتطبيقات الويب التقدمية في [دليل التخزين في المتصفح وPWA](https://arabroot.io/articles/%D8%A7%D9%84%D8%AA%D8%AE%D8%B2%D9%8A%D9%86-%D9%81%D9%8A-%D8%A7%D9%84%D9%85%D8%AA%D8%B5%D9%81%D8%AD-%D9%88%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D9%88%D9%8A%D8%A8-%D8%A7%D9%84%D8%AA%D9%82%D8%AF%D9%85%D9%8A%D8%A9-pwa/).

- المشكلة: تطبيقات تنظيم المجموعات تفشل عند ضعف الشبكة، والرسائل تصل متأخرة أو مكررة.
- المستخدم: قادة المجموعات وأفرادها، ومنظمو الرحلات.
- النطاق: جدول المجموعة ونقاط التجمع وقائمة الأفراد، وتأكيد الحضور عند نقطة التجمع، ومزامنة عند عودة الاتصال، وواجهة بأكثر من لغة لأن المجموعات متعددة الجنسيات. واترك خارج المشروع تتبع المواقع الحي.
- التقنيات: PWA مع IndexedDB، أو Flutter مع SQLite، وخادم مزامنة، ومكتبة لأنواع البيانات القابلة للدمج CRDT إذا أردتم العمق.
- البيانات: إحصاءات الحج المنشورة لدى [الهيئة العامة للإحصاء](https://www.stats.gov.sa/?ref=arabroot.io) لتقدير حجم المستخدمين في المقترح، وسيناريوهات انقطاع تصنعونها أنتم.
- التقييم: محاكي شبكة يقطع الاتصال ويبطئه بنسب مختلفة، ثم قياس نسبة الرسائل التي وصلت ونسبة التعارضات التي حلت صحيحاً، واختبار ميداني مع مجموعة حقيقية إذا أمكن.
- الصعوبة: عالية.
- الخطر الذي يقتلها: أن يختبر الفريق على شبكة الجامعة السريعة فقط، فيبدو كل شيء ممتازاً. لذلك اجعل محاكي الشبكة أول ما تبنيه.
- كيف تتميز: انشر حالات الاختبار التي تصف كل تعارض وكيف حل، فهذه بحد ذاتها مساهمة يستفيد منها غيركم.

### المساهمة في مشروع مفتوح المصدر Open Source كمشروع تخرج

**Project title:** Open Source Contribution as a Graduation Project

هذه الفكرة يرفضها بعض المشرفين في البداية لأنها «ليست مشروعنا»، ولكنها من أقرب الأفكار إلى العمل الحقيقي، فأغلب ما ستفعله في وظيفتك الأولى أن تعدل نظاماً كبيراً كتبه غيرك، وهذا بالضبط ما يطلبه التوجيه الخامس في SE2014 حين يقول إن الطالب يجب أن يواجه نظاماً كبيراً قائماً عليه أن يفهمه ويعدله. والمشروع أن يختار الفريق مشروعاً مفتوح المصدر معروفاً، ويضيف له ميزة حقيقية تهم المستخدم العربي، مثل دعم الاتجاه في محرر نصوص، أو التقويم الهجري في نظام حجوزات، أو تعريب كامل لوحدة في Moodle عبر [منصة الترجمة الخاصة به](https://lang.moodle.org/?ref=arabroot.io)، وقد شرحنا كيف تعمل المجتمعات المفتوحة ومن يقبل المساهمات في [دليل حوكمة المشاريع مفتوحة المصدر](https://arabroot.io/articles/%D8%AD%D9%88%D9%83%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D9%88%D8%A7%D9%84%D9%85%D8%B3%D8%A7%D9%87%D9%85%D8%A9-%D9%81%D9%8A%D9%87%D8%A7/).

- المشكلة: ميزة يحتاجها المستخدمون العرب غير موجودة في مشروع يستخدمه الآلاف.
- المستخدم: مستخدمو المشروع العرب، ومشرفو المشروع Maintainers الذين يراجعون الكود.
- النطاق: ميزة واحدة متوسطة الحجم مقسمة إلى عدة طلبات دمج، مع الاختبارات والتوثيق، ونقاش مع المشرفين قبل الكتابة.
- التقنيات: لغة المشروع نفسه، وهذا هو الجزء الذي ستتعلم منه أكثر.
- البيانات: مستودع المشروع وسجل المهام فيه، و[Good First Issue](https://goodfirstissue.dev/?ref=arabroot.io) للبحث عن المشاريع التي ترحب بالمبتدئين.
- التقييم: عدد طلبات الدمج المقبولة، وعدد جولات المراجعة لكل طلب، والزمن من الفتح إلى الدمج، وتقييم مكتوب من أحد المشرفين إن أمكن.
- الصعوبة: متوسطة إلى عالية بحسب المشروع.
- الخطر الذي يقتلها: أن يرفض المشرفون الميزة أو يتأخروا في المراجعة أشهراً. والحل أن تفتح نقاشاً في سجل المهام قبل أن تبدأ، وتختار مشروعاً يدمج طلبات من خارج فريقه بانتظام، وتحسب ذلك من سجله في أول أسبوع، وسوف ترى في التجربة العملية كيف تختلف نسبة القبول من مجتمع لآخر.
- كيف تتميز: اكتب في التقرير تحليلاً لمعمارية المشروع قبل التعديل وبعده، فهذا ما يحول المساهمة إلى عمل هندسي يقيم.

### لوحة مقاييس الفريق DORA Metrics من Gitea أو GitHub

**Project title:** DORA Metrics Dashboard from Gitea or GitHub

كيف تعرف أن فريقك يسلم بشكل جيد؟ الإجابة السهلة «عدد الأسطر» أو «عدد المهام المغلقة» مضللة، والبحث الذي نشره برنامج [DORA](https://dora.dev/guides/dora-metrics-four-keys/?ref=arabroot.io) يقترح خمسة مقاييس لأداء التسليم: زمن التغيير Change Lead Time من الـ Commit إلى الإنتاج، وتكرار النشر Deployment Frequency، وزمن التعافي من النشر الفاشل Failed Deployment Recovery Time، ونسبة فشل التغيير Change Fail Rate، ونسبة إعادة العمل في النشر Deployment Rework Rate. والمشروع أن تبني لوحة تحسب هذه المقاييس من بيانات المستودع وخط CI ونظام البلاغات، دون أن يدخل أحد شيئاً يدوياً.

- المشكلة: الفرق تقيس إنتاجيتها بأرقام سهلة ومضللة، أو لا تقيس أبداً.
- المستخدم: قادة الفرق التقنية، وفرق مشاريع التخرج نفسها كأول عميل.
- النطاق: قراءة الـ Commits وطلبات الدمج ومرات النشر من [واجهة GitHub البرمجية](https://docs.github.com/en/rest?ref=arabroot.io) أو من Gitea، وتعريف واضح لما يعتبر نشراً فاشلاً، ولوحة أسبوعية لكل فريق.
- التقنيات: Python أو Go، وPostgreSQL، وGrafana أو واجهة بسيطة، وخط CI على [Gitea Actions](https://arabroot.io/articles/gitea-actions-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-ci-cd-%D8%B9%D9%84%D9%89-%D8%AE%D8%A7%D8%AF%D9%85%D9%83/).
- البيانات: مستودعات فرق دفعتكم بعد موافقتهم، ومشاريع مفتوحة المصدر عامة، و[GH Archive](https://www.gharchive.org/?ref=arabroot.io) لأحداث GitHub العامة إذا أردتم حجماً كبيراً.
- التقييم: قارن المقاييس المحسوبة بقياس يدوي على عينة من النشرات، واعرض اللوحة على قادة ثلاثة فرق واسألهم هل غيرت قراراً عندهم.
- الصعوبة: متوسطة.
- الخطر الذي يقتلها: أن تصبح اللوحة أداة لمحاسبة الأفراد، فيرفض الطلاب مشاركة مستودعاتهم. لذلك اجعلها على مستوى الفريق فقط، واكتب ذلك في المقترح.
- كيف تتميز: اربط المقاييس بأحداث حقيقية في مشروعك، مثل أسبوع تأخر فيه الدمج بسبب مراجعة الكود، واشرح ما تعلمتموه منه.

## أفكار رسائل الماجستير Master Theses

الأفكار الست التالية مكتوبة لطالب ماجستير واحد، وكل واحدة تبدأ بسؤال بحث، وفيها مجموعة بيانات Dataset أو معيار Benchmark منشور يستطيع غيرك أن يعيد عليه تجربتك، وهذا أهم ما تبحث عنه اللجنة. ولاحظ أن الذكاء الاصطناعي في هذه الأفكار أداة صغيرة إن وجد، لأن موضوعها جودة البرمجيات، ومن يريد أن يكون النموذج نفسه موضوع الرسالة فمكانه تخصص علم البيانات والذكاء الاصطناعي.

### الاختبارات المتقلبة Flaky Tests: هل يمكن معرفة نوعها من الكود؟

**Project title:** Classifying Flaky Test Root Causes from Source Code

الاختبار المتقلب Flaky Test هو اختبار ينجح مرة ويفشل مرة دون أي تغيير في الكود، وكل من عمل في فريق يعرف كيف يفقد الناس ثقتهم في خط CI بسببه، فيعيدون التشغيل حتى ينجح ثم يتجاهلون الفشل الحقيقي يوماً ما. وللتقلب أنواع: اختبار يعتمد على ترتيب تشغيل الاختبارات Order-Dependent، واختبار يعتمد على سلوك تطبيق معين مثل ترتيب العناصر في HashMap ويسمى Implementation-Dependent، واختبار غير حتمي Non-Deterministic بسبب التزامن أو الوقت. وكل نوع له طريقة إصلاح مختلفة، لذلك فمعرفة النوع قبل الإصلاح توفر وقتاً كبيراً.

- سؤال البحث: هل يمكن تصنيف نوع الاختبار المتقلب من الكود الثابت للاختبار وحده، بدقة تفوق خط الأساس، عندما يكون التقييم على مشاريع لم يرها النموذج؟
- الأعمال السابقة: أدوات الكشف بإعادة التشغيل مثل [iDFlakies](https://github.com/UT-SE-Research/iDFlakies?ref=arabroot.io)، وأبحاث مجموعة جامعة Illinois التي بنت مجموعة البيانات.
- البيانات: [مجموعة الاختبارات المتقلبة الدولية IDoFT](https://github.com/TestingResearchIllinois/idoft?ref=arabroot.io)، وفيها آلاف الاختبارات من مشاريع Java وPython مع نوع كل اختبار وحالة إصلاحه، وهي التي سوف نفحصها في التجربة العملية.
- الإضافة: معالم من الكود الثابت Static Features مثل استخدام الوقت أو الملفات أو الحالة المشتركة، بدل الاعتماد على اسم الاختبار، مع تقييم يفصل المشاريع.
- التقييم: الدقة Accuracy والمقياس F1 لكل نوع، مقابل خط أساس الفئة الأكثر تكراراً، مع تقسيم البيانات حسب المشروع.
- الصعوبة: عالية.
- الخطر الذي يقتلها: تسرب البيانات Data Leakage في التقسيم، وهو ما سوف تراه بالأرقام في التجربة العملية.
- كيف تتميز: أصلح عشرة اختبارات حقيقية من المجموعة وافتح بها طلبات دمج، وأضفها إلى المجموعة نفسها بالطريقة التي يشرحها ملفها التعريفي.

### اختبار الطفرات Mutation Testing: كيف تخفض كلفته دون أن تفقد قيمته؟

**Project title:** Reducing the Cost of Mutation Testing Without Losing Effectiveness

اختبار الطفرات يغير الكود تغييرات صغيرة مقصودة، مثل تحويل > إلى >=، ثم يشغل الاختبارات، فإذا نجحت الاختبارات رغم التغيير فهذا يعني أنها لا تحمي ذلك السطر، وقد شرحناه مع أدواته في [دليل اختبار الطفرات](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%B7%D9%81%D8%B1%D8%A7%D8%AA-mutation-testing/). ومشكلته المعروفة الكلفة، فكل طفرة تحتاج تشغيل الاختبارات من جديد. وقد درس بحث من Google بعنوان [Does mutation testing improve testing practices?](https://arxiv.org/abs/2103.07189?ref=arabroot.io) قرابة 15 مليون طفرة، ووجد أن المطورين الذين يستخدمون اختبار الطفرات يكتبون اختبارات أكثر، وأن الطفرات مرتبطة بالأخطاء الحقيقية، ولكن Google تملك بنية تشغيل لا تملكها فرق صغيرة.

- سؤال البحث: هل يحقق اختيار الطفرات على الأسطر المتغيرة في طلب الدمج فقط، مع ترتيبها حسب نوع المعامل، نفس القدرة على كشف الأخطاء الحقيقية بجزء صغير من الوقت؟
- البيانات: [Defects4J](https://github.com/rjust/defects4j?ref=arabroot.io)، وفيه 854 خطأ حقيقياً قابلاً للإعادة من مشاريع Java مفتوحة المصدر، مع الإصدار المعيب والمصلح لكل خطأ.
- الأدوات: [PIT](https://pitest.org/?ref=arabroot.io) لـ Java، أو [Stryker](https://stryker-mutator.io/?ref=arabroot.io) إذا اخترت JavaScript، أو [mutmut](https://github.com/boxed/mutmut?ref=arabroot.io) لـ Python.
- التقييم: نسبة الأخطاء الحقيقية في Defects4J التي كانت ستكتشف، ووقت التشغيل، مقابل التشغيل الكامل كخط أساس.
- الصعوبة: عالية.
- الخطر الذي يقتلها: وقت التجارب نفسها، فتشغيل الطفرات على مئات الأخطاء قد يأخذ أسابيع على جهاز واحد. لذلك احسب الوقت على خمسة أخطاء في الشهر الأول، وقرر عدد المشاريع بناءً عليه.
- كيف تتميز: انشر كل سكربتات التجربة والنتائج الخام حتى يعيدها غيرك بأمر واحد.

### الاختبار القائم على الخصائص Property-Based Testing للنص العربي Bidi

**Project title:** Property-Based Testing of Arabic Bidi Text Handling

في الاختبار العادي تكتب مثالاً ومخرجه المتوقع، أما في الاختبار القائم على الخصائص فتكتب خاصية يجب أن تتحقق لكل مدخل، مثل «تحويل النص إلى ترميز ثم إعادته يعطي نفس النص»، وتترك الأداة تولد آلاف المدخلات وتبحث عن مدخل يخالف الخاصية ثم تصغره إلى أبسط شكل. وأغلب المولدات الافتراضية في [Hypothesis](https://hypothesis.readthedocs.io/en/latest/?ref=arabroot.io) و[fast-check](https://fast-check.dev/?ref=arabroot.io) تولد نصوصاً عشوائية من Unicode كله، فلا تقترب من الحالات التي تفشل فيها البرامج مع العربية: الأرقام بين كلمتين عربيتين، وعلامات التحكم في الاتجاه، والتطويل، والحروف المركبة، والأرقام الهندية. وقد شرحنا هذه الحالات في [دليل ترميز النصوص](https://arabroot.io/articles/%D8%AA%D8%B1%D9%85%D9%8A%D8%B2-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-ascii-%D9%88-unicode-%D9%88-utf-8-%D9%88%D8%A7%D9%84%D8%AD%D8%B1%D9%88%D9%81-%D8%A7%D9%84%D9%85%D8%B4%D9%88%D9%87%D8%A9/) و[دليل التعريب](https://arabroot.io/articles/%D8%A7%D9%84%D8%AA%D8%B9%D8%B1%D9%8A%D8%A8-i18n-%D9%88%D8%A7%D9%84%D9%86%D8%B5-%D8%AB%D9%86%D8%A7%D8%A6%D9%8A-%D8%A7%D9%84%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-bidi-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86/).

- سؤال البحث: هل يكتشف مولد مدخلات مصمم للنص العربي وثنائي الاتجاه أخطاء أكثر في مكتبات معالجة النص الشائعة من المولد العام، بنفس عدد المدخلات؟
- البيانات: مجموعة مكتبات مفتوحة المصدر للتنسيق والبحث وقص النص والقوالب، ونصوص عربية حقيقية من مجموعات البيانات المفهرسة في [مصادر Masader](https://arbml.github.io/masader/?ref=arabroot.io) لبناء توزيع واقعي للحروف.
- الإضافة: مولد مفتوح المصدر للنص العربي، وقائمة خصائص قابلة لإعادة الاستخدام لكل نوع مكتبة.
- التقييم: عدد الأخطاء الفريدة المكتشفة، والزمن حتى أول خطأ، مقابل المولد العام، مع تأكيد كل خطأ يدوياً وفتح بلاغ للمكتبة.
- الصعوبة: عالية.
- الخطر الذي يقتلها: أن تكون كل الأخطاء المكتشفة «سلوكاً متوقعاً» في نظر مطوري المكتبة. لذلك اعتمد على تعريف صحيح من مواصفة Unicode قبل أن تعتبر أي سلوك خطأ.
- كيف تتميز: كل بلاغ يقبله مطورو مكتبة معروفة هو دليل في الرسالة، وقد يصبح المولد نفسه حزمة يستخدمها الناس.

### الدين التقني المعترف به Self-Admitted Technical Debt

**Project title:** Mining Self-Admitted Technical Debt from Code Comments

عندما يكتب المطور في الكود تعليقاً مثل TODO أو «هذا حل مؤقت» فهو يعترف بدين تقني Technical Debt، أي اختصار سوف يدفع ثمنه لاحقاً. وهذه التعليقات بيانات ممتازة لأنها مكتوبة بيد المطور نفسه، ومجموعة [بيانات SATD المصنفة يدوياً](https://github.com/maldonado/tse.satd.data?ref=arabroot.io) التي نشرها Maldonado وShihab مع بحثهم عن الكشف الآلي متاحة للجميع، وهناك أيضاً [Technical Debt Dataset](https://github.com/clowee/The-Technical-Debt-Dataset?ref=arabroot.io) الذي حلل كل الـ Commits في 31 مشروع Java بأدوات منها SonarQube، وقد شرحنا SonarQube عملياً في [دليل SonarQube](https://arabroot.io/articles/sonarqube-%D8%B9%D9%85%D9%84%D9%8A%D8%A7-%D8%A8%D9%88%D8%A7%D8%A8%D8%A9-%D8%AC%D9%88%D8%AF%D8%A9-%D9%84%D9%83%D9%88%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/).

- سؤال البحث: هل الأجزاء التي فيها دين معترف به أكثر عرضة للأخطاء من غيرها، وكم تبقى قبل أن تسدد؟ وهل تتفق تنبيهات أدوات التحليل الثابت مع ما يعترف به المطورون؟
- البيانات: المجموعتان أعلاه، وتاريخ الـ Commits من المستودعات نفسها.
- الإضافة: الربط بين الدين المعترف به والدين الذي تكشفه الأدوات، فإذا اختلفا فما الذي لا تراه الأدوات؟
- التقييم: تحليل إحصائي على مستوى الملف مع اختبار دلالة، ومقابلات قصيرة مع خمسة مطورين لتفسير النتائج.
- الصعوبة: متوسطة إلى عالية.
- الخطر الذي يقتلها: أن تخلط الارتباط بالسببية، فالملفات الكبيرة فيها تعليقات أكثر وأخطاء أكثر لأنها كبيرة فقط. لذلك ضع حجم الملف متغيراً ضابطاً من البداية.
- كيف تتميز: كرر التحليل على مشاريع عربية أو سعودية مفتوحة المصدر، وقارن هل تختلف لغة الاعتراف بالدين.

### اختبار العقود Contract Testing مقابل اختبار التكامل Integration Testing

**Project title:** Contract Testing Versus Integration Testing for Microservices

في نظام Microservices يتصل كل جزء بأجزاء أخرى عبر واجهات، واختبار التكامل التقليدي يشغل كل الخدمات معاً ويختبرها، وهذا بطيء وهش، أما اختبار العقود فيختبر كل خدمة وحدها مقابل عقد مكتوب لما ينتظره منها المستهلك، وقد شرحناه مع Pact في [دليل اختبار العقود](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%B9%D9%82%D9%88%D8%AF-contract-testing-%D9%85%D8%B9-pact/). والسؤال الذي لا تجد له أرقاماً كثيرة: كم من الأخطاء التي يكتشفها اختبار التكامل يكتشفها اختبار العقود، وبأي كلفة؟

- سؤال البحث: عند إدخال تغييرات غير متوافقة في الواجهة في نظام Microservices معياري، ما نسبة ما يكتشفه اختبار العقود مقابل اختبار التكامل الكامل، وما الفرق في الوقت والموارد؟
- البيانات: [Train Ticket](https://github.com/FudanSELab/train-ticket?ref=arabroot.io)، وهو نظام حجز تذاكر مبني من 41 خدمة صغيرة نشر كمعيار بحثي، أو [DeathStarBench](https://github.com/delimitrou/DeathStarBench?ref=arabroot.io).
- الإضافة: تصنيف لتغييرات الواجهة يبين أيها يفلت من العقود ولماذا.
- التقييم: إدخال تغييرات مقصودة بطريقة الطفرات على مستوى الواجهة، وقياس الاكتشاف والوقت للطريقتين.
- الصعوبة: عالية جداً.
- الخطر الذي يقتلها: تشغيل 41 خدمة يحتاج موارد كبيرة، فإذا لم يعمل النظام على جهازك في الشهر الأول فاختر مجموعة فرعية من الخدمات أو نظاماً أصغر.
- كيف تتميز: انشر العقود التي كتبتها للنظام كمساهمة في مستودعه، فتصبح تجربتك قابلة للإعادة من غيرك.

### عيوب المتطلبات العربية Requirements Smells في كراسات المنافسات

**Project title:** Detecting Requirements Smells in Arabic Tender Documents

عيوب المتطلبات Requirements Smells فكرة نقلت من عيوب الكود Code Smells إلى المتطلبات، فالمتطلب الذي فيه «سريع» أو «سهل الاستخدام» دون رقم، أو «يجب أن يدعم النظام كل التقارير اللازمة»، متطلب لا يمكن اختباره. وقد بنى Femmer وزملاؤه أداة لكشف هذه العيوب في المتطلبات الإنجليزية ونشروها في بحث [Rapid quality assurance with Requirements Smells](https://arxiv.org/abs/1611.08847?ref=arabroot.io)، ووصلت الأداة في تقييمهم إلى دقة 59% واستدعاء 82% في المتوسط. أما المتطلبات العربية فلا نعرف عملاً منشوراً بنفس الحجم عليها، رغم أن كراسات الشروط والمواصفات في المنافسات الحكومية المنشورة عبر [منصة اعتماد](https://tenders.etimad.sa/?ref=arabroot.io) مكتوبة بالعربية، وهي التي تحدد ما ستبنيه الشركات.

- سؤال البحث: ما العيوب الأكثر تكراراً في المتطلبات التقنية العربية، وهل تستطيع قواعد لغوية بسيطة أن تكشفها بدقة قريبة من الأدوات الإنجليزية؟
- البيانات: عينة من كراسات منشورة للعموم، تصنفها أنت وزميل آخر يدوياً، مع حساب الاتفاق بينكما.
- الإضافة: أول قائمة عيوب عربية مع أمثلة، وأداة قواعد مفتوحة المصدر، ومجموعة بيانات مصنفة.
- التقييم: الدقة والاستدعاء مقابل التصنيف اليدوي، ومقابلات مع محللي متطلبات يقرؤون مخرجات الأداة.
- الصعوبة: عالية.
- الخطر الذي يقتلها: شروط استخدام الوثائق، لذلك اقرأها قبل أن تجمع، واستشر لجنة الأخلاقيات في الجامعة إذا كانت هناك مقابلات، كما شرحنا في [دليل أخلاقيات البحث](https://arabroot.io/articles/%D8%A7%D8%AE%D9%84%D8%A7%D9%82%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D8%A8%D8%B4%D8%B1-%D9%85%D9%86-%D9%84%D8%AC%D9%86%D8%A9-irb-%D8%A7%D9%84%D9%89-%D8%AD%D9%85%D8%A7%D9%8A%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/).
- كيف تتميز: انشر المجموعة المصنفة بترخيص يسمح بإعادة الاستخدام، فتصبح مرجعاً يستشهد به من بعدك.

## الأفكار المستهلكة Overused Ideas: كيف تنقذ واحدة منها؟

قبل أن نصل إلى جدول المقارنة، لنعد إلى قائمة الدفعات السابقة التي فتحتها في البداية. هناك أفكار يراها المشرفون كل فصل حتى ملوها، وأشهرها:

- نظام الحضور Attendance System بالبصمة أو الوجه أو رمز QR.
- المتجر الإلكتروني E-Commerce العام لمنتج ما.
- روبوت محادثة Chatbot للجامعة يجيب عن أسئلة الطلاب.
- نظام إدارة مكتبة Library System أو نظام حجز مواعيد عيادة.
- تطبيق «توصيل» أو «حجز ملاعب» يكرر تطبيقاً تجارياً موجوداً.

والمشكلة في هذه الأفكار ليست أنها سهلة، وإنما أن أغلب من قدموها بنوا نسخة من نظام موجود دون سؤال جديد، ودون مستخدم حقيقي، ودون قياس، فأصبحت اللجنة تعرف مسبقاً كيف ستبدو الشاشات، وما الأسئلة التي لن يجيب عنها الفريق. ولكن أي فكرة منها يمكن إنقاذها إذا أضفت لها واحداً من ثلاثة أشياء: قيداً حقيقياً صعباً، أو معياراً خارجياً، أو تقييماً جاداً. والصورة التالية تبين كيف يتحول نظام الحضور إلى مشروع له قيمة.

![رسم تحويل من اليمين إلى اليسار: فكرة نظام حضور برمز QR عادية، ثم ثلاث إضافات، قيد حقيقي وهو رمز يتغير كل عشر ثوان وتسجيل دون اتصال في قاعات ضعيفة الشبكة، ومعيار خارجي وهو سهولة الوصول WCAG 2.2 والخصوصية، وتقييم جاد وهو قياس زمن تسجيل قاعة من 60 طالباً ونسبة التسجيل بالنيابة قبل وبعد، والنتيجة مشروع قابل للمناقشة](https://arabroot.io/content/images/2026/11/grad-projects-se-03-overused.webp)

نفس فكرة الحضور، ولكن بقيد حقيقي ومعيار خارجي وتقييم يقاس

لنأخذ نظام الحضور مثالاً كاملاً. النسخة المعتادة: الطالب يمسح رمز QR على الشاشة، ويسجل حضوره، وانتهى. والمشكلة الحقيقية التي يعرفها كل أستاذ أن الطالب يرسل صورة الرمز لزميله الغائب، وأن شبكة القاعة تنهار عندما يمسح ستون طالباً في نفس الدقيقة. فإذا جعلت المشروع عن هاتين المشكلتين، أي رمز يتغير كل عشر ثوان ويوقع بمفتاح، وتحقق من القرب دون تتبع موقع الطالب، وتسجيل يعمل دون اتصال ثم يزامن، فقد أصبح لديك سؤال هندسي، ونموذج تهديدات، واختبار أداء Load Testing، ومسألة خصوصية يجب أن تناقشها. وإذا قست في النهاية زمن تسجيل قاعة كاملة ونسبة التسجيل بالنيابة قبل النظام وبعده، فلن تسألك اللجنة «ما الجديد؟» لأنك أجبت بالأرقام.

ونفس الطريقة تصلح للمتجر الإلكتروني: بدلاً من متجر عام، ابن متجراً يلتزم بالفوترة الإلكترونية ويقيس زمن إصدار الفاتورة، أو متجراً يختبر الاتجاه وسهولة الوصول في كل طلب دمج. وروبوت المحادثة للجامعة يتحول إلى مشروع هندسي إذا كان السؤال عن الجودة: كيف تختبر أن إجاباته صحيحة بعد كل تحديث للوائح؟ وكيف تبني مجموعة اختبارات من أسئلة حقيقية جمعتها من شؤون الطلاب؟ وهنا يصبح الذكاء الاصطناعي جزءاً صغيراً، والاختبار والتقييم هما المشروع، وقد ناقشنا هذا النوع من الاختبار في [دليل أتمتة الاختبارات بالذكاء الاصطناعي](https://arabroot.io/articles/%D8%A7%D8%AA%D9%85%D8%AA%D8%A9-%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1%D8%A7%D8%AA-%D8%A8%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/).

## جدول مقارنة الأفكار Comparison Table

الجدول التالي يجمع الأفكار الخمس عشرة في مكان واحد. وتوفر البيانات Data Availability يعني: عالية إذا كانت البيانات منشورة وتستطيع تحميلها اليوم، ومتوسطة إذا كانت تحتاج تجميعاً أو تسجيلاً في بيئة اختبار، ومنخفضة إذا كانت تعتمد على جهة خارجية أو على مستخدمين يجب أن تجندهم.

| الفكرة                                                                                             | المستوى   | الصعوبة          | توفر البيانات | المهارات التي تتعلمها                                    |
| -------------------------------------------------------------------------------------------------- | --------- | ---------------- | ------------- | -------------------------------------------------------- |
| مدقق الواجهات العربية RTL LinterRTL Linter for Arabic Web Interfaces                               | بكالوريوس | متوسطة           | عالية         | تحليل CSS، المتصفح بلا واجهة، CI، قياس Precision وRecall |
| مراقب سهولة الوصول AccessibilityAccessibility Monitor for Government Digital Services              | بكالوريوس | متوسطة           | عالية         | WCAG، الأتمتة، تخزين النتائج عبر الزمن، دراسة مستخدمين   |
| تتبع المتطلبات TraceabilityRequirements-to-Test Traceability Tool                                  | بكالوريوس | متوسطة           | عالية         | هندسة المتطلبات، Git، أدوات المطور                       |
| بلاغات البلدية Open311Open311 Municipal Issue Reporting Portal with Clean Architecture             | بكالوريوس | متوسطة إلى عالية | متوسطة        | المعايير المفتوحة، Clean Architecture، PostGIS، SUS      |
| تقسيم المصروفات Open BankingExpense Splitting App with Open Banking Integration                    | بكالوريوس | عالية            | متوسطة        | الموافقة والتوكن، Property Tests، نموذج التهديدات        |
| مكتبة الفوترة ZATCAOpen Source ZATCA E-Invoicing Library for Small Merchants                       | بكالوريوس | عالية            | متوسطة        | بناء مكتبة، الاختبار مقابل مواصفة، الإصدارات والتراخيص   |
| مجموعات الحج والعمرة Offline-FirstOffline-First App for Hajj and Umrah Groups                      | بكالوريوس | عالية            | منخفضة        | المزامنة، CRDT، محاكاة الشبكة، الاختبار الميداني         |
| المساهمة في مشروع Open SourceOpen Source Contribution as a Graduation Project                      | بكالوريوس | متوسطة إلى عالية | عالية         | قراءة كود كبير، مراجعة الكود، التواصل مع المشرفين        |
| لوحة DORA MetricsDORA Metrics Dashboard from Gitea or GitHub                                       | بكالوريوس | متوسطة           | عالية         | واجهات Git البرمجية، تعريف المقاييس، لوحات البيانات      |
| الاختبارات المتقلبة Flaky TestsClassifying Flaky Test Root Causes from Source Code                 | ماجستير   | عالية            | عالية         | تصميم التجارب، تسرب البيانات، تحليل الكود الثابت         |
| اختبار الطفرات Mutation TestingReducing the Cost of Mutation Testing Without Losing Effectiveness  | ماجستير   | عالية            | عالية         | Defects4J، PIT، قياس الكلفة والفعالية                    |
| Property-Based Testing للنص العربيProperty-Based Testing of Arabic Bidi Text Handling              | ماجستير   | عالية            | عالية         | Unicode وBidi، المولدات، تأكيد الأخطاء                   |
| الدين التقني SATDMining Self-Admitted Technical Debt from Code Comments                            | ماجستير   | متوسطة إلى عالية | عالية         | تحليل المستودعات، الإحصاء، المتغيرات الضابطة             |
| اختبار العقود Contract TestingContract Testing Versus Integration Testing for Microservices        | ماجستير   | عالية جداً       | عالية         | Microservices، Pact، حقن التغييرات                       |
| عيوب المتطلبات العربية Requirements SmellsDetecting Requirements Smells in Arabic Tender Documents | ماجستير   | عالية            | متوسطة        | التصنيف اليدوي، الاتفاق بين المصنفين، القواعد اللغوية    |

وإذا كان فريقكم يميل إلى الكود أكثر من المستخدمين فابدأوا من الأدوات في أول الجدول، لأن تقييمها أوضح، وإذا كان فيكم من يحب المقابلات والتصميم فالأنظمة الحقيقية في وسطه أنسب، لأن قيمتها في المستخدم. أما طالب الماجستير فليختر الفكرة التي يجد لها بيانات عالية التوفر، لأن الرسالة التي تنتظر بيانات من جهة خارجية تتأخر في الغالب فصلاً أو فصلين.

## تجربة عملية Lab: تجربة جدوى Feasibility Spike للاختبارات المتقلبة

قلنا إن أهم حقل في البطاقة هو الخطر الذي يقتل الفكرة، وإن عليك أن تختبره في أول أسبوعين. والآن سوف نفعل ذلك على فكرة الماجستير الأولى، الاختبارات المتقلبة، لأنها تعتمد على مجموعة بيانات منشورة، وأي طالب يستطيع أن يعيد ما سنفعله في ساعة. وتجربة الجدوى Spike في هندسة البرمجيات عمل قصير هدفه الإجابة عن سؤال واحد قبل أن تلتزم بالتصميم، وليس بناء جزء من النظام. وأسئلتنا هنا أربعة، وهي نفس الأسئلة التي سيطرحها المشرف:

1. هل البيانات كبيرة بما يكفي، وما حالتها، وكم تحتاج من التنظيف؟
2. إذا كانت الفكرة تشمل إصلاح اختبارات وفتح طلبات دمج، فكم من هذه الطلبات يقبلها المشرفون فعلاً؟
3. هل تتركز البيانات في مشاريع قليلة، بحيث يتعلم النموذج المشروع بدلاً من النوع؟
4. ما خط الأساس الذي يجب أن تتفوق عليه الرسالة، وهل تغير طريقة تقسيم البيانات النتيجة؟

والصورة التالية تبين خطوات التجربة من التحميل إلى خط الأساس، مع الأرقام التي خرجت في كل خطوة.

![أربع بطاقات مرقمة: تحميل ملفي IDoFT بحجم 2.3 ميجابايت تقريباً عند Commit ثابت 4903dc9، ثم التنظيف وفيه 132 صفاً بأكثر من نوع و8 حالات Open بدل Opened ومشاريع Python من 343 إلى 342 بعد توحيد الروابط و138 اختباراً مكرراً، ثم الحجم وفيه 8075 صفاً في Java من 481 مشروعاً و1618 في Python من 342 وأكبر نوع ID بـ 5201 ونصيب أكبر عشرة مشاريع 33.6%، ثم خط الأساس وفيه الفئة الأكثر تكراراً ID ونموذج Naive Bayes وتقسيمان وخمس بذور](https://arabroot.io/content/images/2026/11/grad-projects-se-04-spike.webp)

تجربة الجدوى في أربع خطوات: تحميل ثابت، تنظيف، إحصاءات، ثم خط أساس

### بيانات IDoFT Dataset ولماذا اخترناها

مجموعة [IDoFT](https://github.com/TestingResearchIllinois/idoft?ref=arabroot.io) مستودع عام على GitHub يجمع الاختبارات المتقلبة التي اكتشفت في مشاريع مفتوحة المصدر، في ملف للمشاريع المكتوبة بلغة Java اسمه pr-data.csv وملف لمشاريع Python اسمه py-data.csv، وفي كل صف رابط المشروع، ورقم الـ Commit الذي اكتشف فيه التقلب، واسم الاختبار، ونوع التقلب Category، وحالة الإصلاح Status، ورابط طلب الدمج الذي حاول الإصلاح إن وجد. ويشرح الملف التعريفي للمستودع معنى كل نوع: OD للاختبار المعتمد على الترتيب، وOD-Vic للاختبار الضحية الذي يفشل إذا شغل بعد اختبار آخر يلوث الحالة، وOD-Brit للاختبار الهش الذي ينجح فقط إذا شغل بعد اختبار آخر يجهز له الحالة، وID للاختبار المعتمد على التطبيق الذي تكشفه أداة NonDex، وNOD للاختبار غير الحتمي، وNIO للاختبار الذي ينجح في التشغيل الأول ويفشل في الثاني، وTD للاختبار المعتمد على الوقت، وغيرها. ويشرح أيضاً حالات الإصلاح: Opened إذا فتح طلب دمج، وAccepted إذا قبل، وRejected إذا رفضه المطورون لأنهم لم يروا حاجة للإصلاح، وInspiredAFix إذا ألهم العمل إصلاحاً كتبه المطورون أنفسهم، وUnmaintained للمستودع الذي لم يتغير منذ سنتين.

ولاحظ أن المستودع يتغير باستمرار لأن الناس يضيفون له، لذلك فأول قرار في أي تجربة قابلة للإعادة أن تثبت الإصدار. والسكربت التالي ينزل الملفين عند Commit محدد قرأناه في 1 نوفمبر 2026، فإذا شغلته بعد سنة سوف تحصل على نفس الأرقام:

```bash
#!/bin/sh
# Downloads the two IDoFT CSV files (about 2.3 MB) at a fixed commit, so the numbers in the article can be reproduced.
#   sh fetch_idoft.sh [commit]     (default: the commit read on 2026-11-01)
C=${1:-4903dc9233eead4e4191c66f9ed0b14eea091052}
mkdir -p data
for f in pr-data.csv py-data.csv; do
  curl -sfL -o "data/$f" "https://raw.githubusercontent.com/TestingResearchIllinois/idoft/$C/$f" || { echo "failed: $f"; exit 1; }
  echo "$f $(wc -l < data/$f) lines"
done
```

والمخرج سوف يكون كما يلي:

```text
pr-data.csv 8076 lines
py-data.csv 1619 lines
```

والسطر الزائد في كل ملف هو سطر العناوين. وأول مشكلة ظهرت لنا قبل هذا السكربت: حاولنا تنزيل الملف التعريفي باسم README.md كما هو معتاد، فرجع ملف فارغ، والسبب أن اسمه في المستودع readme.md بحروف صغيرة، وروابط الملفات الخام في GitHub تفرق بين الحالتين. لذلك استخدمنا واجهة GitHub لعرض محتويات المستودع أولاً، ومنها عرفنا الأسماء الصحيحة، وهذا درس صغير: لا تفترض اسم ملف، واقرأه من المصدر.

### البرنامج idoft\_spike.py

البرنامج التالي مكتوب بلغة Python 3.13 بالمكتبة الأساسية فقط، ويجيب عن الأسئلة الأربعة بالترتيب، ويطبع كل قسم تحت عنوان مرقم:

```python
# Feasibility spike for a flaky-test graduation project: is the IDoFT dataset big and clean enough,
# how often do fix PRs get accepted, and what baseline must a Master's model beat?
#   python idoft_spike.py data/pr-data.csv data/py-data.csv
# Python 3.13, standard library only. Data: https://github.com/TestingResearchIllinois/idoft (see fetch_idoft.sh).
import csv, math, random, re, sys
from collections import Counter, defaultdict

def load(path, lang):
    rows = []
    with open(path, encoding='utf-8', newline='') as f:
        for r in csv.DictReader(f):
            name_col = next(k for k in r if k.startswith(('Fully-Qualified', 'Pytest')))
            rows.append({'lang': lang, 'project_raw': r['Project URL'], 'project': r['Project URL'].strip().lower().rstrip('/'),
                         'test': r[name_col].strip(), 'cat_raw': r['Category'].strip(),
                         'status_raw': r['Status'], 'pr': r['PR Link'].strip()})
    return rows

STATUS_FIX = {'Open': 'Opened'}   # variants found in the file

def clean(rows):
    fixes = Counter()
    for r in rows:
        s = r['status_raw'].strip()
        if s != r['status_raw']: fixes['status with spaces'] += 1
        if s in STATUS_FIX: fixes[f'status {s!r} -> {STATUS_FIX[s]!r}'] += 1; s = STATUS_FIX[s]
        r['status'] = s or '(none)'
        r['cats'] = [c for c in r['cat_raw'].split(';') if c] or ['(none)']
        if len(r['cats']) > 1: fixes['rows with several categories'] += 1
    return fixes

def pct(a, b): return f'{100 * a / b:5.1f}%' if b else '   - '

def section(t): print(f'\n== {t} ==')

java = load(sys.argv[1], 'java'); py = load(sys.argv[2], 'python'); rows = java + py

section('0) cleaning')
for k, v in sorted(clean(rows).items()): print(f'{k:38} {v:5}')
for lang in ('java', 'python'):
    raw = {r['project_raw'] for r in rows if r['lang'] == lang}; norm = {r['project'] for r in rows if r['lang'] == lang}
    print(f'{lang + " project URLs, raw -> normalized":38} {len(raw):5} -> {len(norm)}')
dups = len(rows) - len({(r['project'], r['test']) for r in rows})
print(f'{"duplicate (project, test) pairs":38} {dups:5}')

section('1) size of the dataset')
for lang, rs in (('java', java), ('python', py)):
    print(f'{lang:7} rows {len(rs):5}  projects {len({r["project"] for r in rs}):4}  tests {len({(r["project"], r["test"]) for r in rs}):5}')
for lang, rs in (('java', java), ('python', py)):
    c = Counter(cat for r in rs for cat in r['cats'])
    print(f'{lang:7} top categories: ' + ', '.join(f'{k} {v}' for k, v in c.most_common(6)))

section('2) what happened to the fix PRs (rows with a PR link)')
DECIDED_OK, DECIDED_NO = {'Accepted', 'InspiredAFix'}, {'Rejected', 'DeveloperWontFix', 'DevelopersDoNotWantFix'}
for lang, rs in (('java', java), ('python', py)):
    with_pr = [r for r in rs if r['pr']]
    c = Counter(r['status'] for r in with_pr)
    ok = sum(c[s] for s in DECIDED_OK); no = sum(c[s] for s in DECIDED_NO); waiting = c['Opened']
    print(f'{lang:7} with PR {len(with_pr):5}  accepted/inspired {ok:5}  rejected/won\'t fix {no:4}  still open {waiting:5}'
          f'  acceptance of decided {pct(ok, ok + no)}')
    print(f'        statuses: ' + ', '.join(f'{k} {v}' for k, v in c.most_common(8)))

section('3) concentration: share of rows in the 10 biggest projects')
for lang, rs in (('java', java), ('python', py)):
    c = Counter(r['project'] for r in rs); top = c.most_common(10)
    print(f'{lang:7} top-10 share {pct(sum(v for _, v in top), len(rs))}  biggest: {top[0][0].split("github.com/")[-1]} ({top[0][1]} rows)')

section('4) baseline: guess the category of a Java flaky test from its name only')
def tokens(name):
    parts = re.split(r'[.\[\]()#_$]+', name)
    out = []
    for p in parts:
        out += [w.lower() for w in re.findall(r'[A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|\d+', p)]
    return out

data = [(tokens(r['test']), r['cats'][0], r['project']) for r in java if len(r['cats']) == 1 and r['cats'][0] != '(none)']

def train_nb(train):
    prior, words, total, vocab = Counter(), defaultdict(Counter), Counter(), set()
    for toks, y, _ in train:
        prior[y] += 1; words[y].update(toks); total[y] += len(toks); vocab.update(toks)
    V = len(vocab)
    def predict(toks):
        return max(prior, key=lambda y: math.log(prior[y]) + sum(math.log((words[y][t] + 1) / (total[y] + V)) for t in toks))
    return predict

def evaluate(train, test):
    majority = Counter(y for _, y, _ in train).most_common(1)[0][0]
    nb = train_nb(train)
    acc_m = sum(y == majority for _, y, _ in test) / len(test)
    acc_nb = sum(nb(t) == y for t, y, _ in test) / len(test)
    return majority, acc_m, acc_nb

rnd = random.Random(2026)
shuffled = data[:]; rnd.shuffle(shuffled)
cut = int(len(shuffled) * .8)
maj, am, anb = evaluate(shuffled[:cut], shuffled[cut:])
print(f'random 80/20 split      test rows {len(shuffled) - cut:5}  majority ({maj}) {am:.3f}  naive bayes {anb:.3f}')

projects = sorted({p for _, _, p in data}); rnd.shuffle(projects)
test_p = set(projects[:len(projects) // 5])
tr = [d for d in data if d[2] not in test_p]; te = [d for d in data if d[2] in test_p]
maj, am, anb = evaluate(tr, te)
print(f'split by project 80/20  test rows {len(te):5}  majority ({maj}) {am:.3f}  naive bayes {anb:.3f}')

section('5) what if: the same two splits over 5 different seeds')
for seed in range(5):
    r2 = random.Random(seed); s = data[:]; r2.shuffle(s); c = int(len(s) * .8)
    _, am1, nb1 = evaluate(s[:c], s[c:])
    ps = projects[:]; r2.shuffle(ps); tp = set(ps[:len(ps) // 5])
    _, am2, nb2 = evaluate([d for d in data if d[2] not in tp], [d for d in data if d[2] in tp])
    print(f'seed {seed}  random: majority {am1:.3f} nb {nb1:.3f}   by project: majority {am2:.3f} nb {nb2:.3f}')
```

في البرنامج أعلاه لاحظ التالي:

- الدالة load توحد الملفين، لأن اسم عمود الاختبار مختلف بينهما، ففي Java يبدأ بـ Fully-Qualified وفي Python يبدأ بـ Pytest، والبرنامج يبحث عن العمود بالبداية بدلاً من كتابة الاسم الطويل كاملاً، ويوحد رابط المشروع بالحروف الصغيرة وحذف الشرطة المائلة الأخيرة.
- الدالة clean تسجل كل إصلاح تقوم به في عداد، حتى يظهر في المخرج كم صفاً تغير ولماذا، وهذا ما ستكتبه في فصل البيانات في الرسالة.
- القسم الثاني يحسب نسبة القبول من الطلبات التي حسمت فقط، أي المقبولة والمرفوضة، ويترك المفتوحة جانباً، والسبب أن الطلب المفتوح لم يقرر فيه أحد بعد، فإذا حسبته مرفوضاً ظلمت المشروع، وإذا حسبته مقبولاً بالغت.
- القسم الرابع يبني نموذج Naive Bayes بسيطاً على الكلمات في اسم الاختبار، مثل testCompositeKeys التي تتحول إلى test وcomposite وkeys. وهذا ليس النموذج الذي تقترحه الرسالة، وإنما خط أساس رخيص، والسؤال هو: ماذا يحدث له عندما نغير طريقة التقسيم؟
- البذرة Seed ثابتة بقيمة 2026، حتى يعطي التشغيل نفس الأرقام كل مرة.

وللتشغيل من مجلد lab بعد تنزيل البيانات:

```bash
sh fetch_idoft.sh
python idoft_spike.py data/pr-data.csv data/py-data.csv > idoft_spike.out
```

ويأخذ التشغيل نحو ثلاث ثوان على جهاز محمول عادي، وأغلبها في القسم الخامس الذي يدرب النموذج عشر مرات.

### المخرج الأول: تنظيف البيانات Data Cleaning والمشكلات الحقيقية

```text
== 0) cleaning ==
rows with several categories             132
status 'Open' -> 'Opened'                  8
status with spaces                         1
java project URLs, raw -> normalized     481 -> 481
python project URLs, raw -> normalized   343 -> 342
duplicate (project, test) pairs          138
```

هذا القسم لم يكن موجوداً في النسخة الأولى من البرنامج، وأضفناه بعد أن ظهرت أرقام غريبة في أول عد للأنواع والحالات، وكل سطر فيه مشكلة حقيقية وجدناها في البيانات:

- 132 صفاً فيها أكثر من نوع مفصول بفاصلة منقوطة، مثل NDOD;TD، وهذا مسموح في الملف التعريفي للمستودع. ولو عددنا الأنواع كنصوص كما هي لظهر NDOD;TD كنوع مستقل بجانب NDOD وTD، وهذا ما رأيناه فعلاً في أول عد. لذلك قسمنا كل صف إلى أنواعه في الإحصاءات، واستبعدنا الصفوف متعددة الأنواع من التصنيف في القسم الرابع، لأن النموذج البسيط يتنبأ بنوع واحد.
- 8 صفوف حالتها Open بدلاً من Opened، وصف واحد فيه مسافة بعد الكلمة، وهذه أخطاء كتابة طبيعية في ملف يحرره مئات الأشخاص يدوياً. ولو تركناها لظهرت في الإحصاءات كحالات مستقلة لا يعرفها الملف التعريفي.
- عدد مشاريع Python ينزل من 343 إلى 342 بعد توحيد الروابط، والسبب أن مشروعاً واحداً كتب رابطه مرة بشرطة مائلة في آخره ومرة دونها. وهذه مشكلة صغيرة هنا، ولكنها خطيرة في القسم الرابع، لأن تقسيم البيانات حسب المشروع سوف يضع نصف المشروع في التدريب ونصفه في الاختبار دون أن تنتبه.
- 138 زوجاً مكرراً من المشروع واسم الاختبار، وعندما فحصنا أمثلة منها وجدنا أن الاختبار نفسه سجل مرتين بـ Commit مختلف أو مسار وحدة مختلف، وحالته في مرة Irreproducible وفي الأخرى MovedOrRenamed. وهذا يعني أن الصف في هذه المجموعة ليس اختباراً فريداً بالضرورة، وأن عليك أن تقرر في الرسالة: هل وحدة التحليل هي الصف أم الاختبار؟

### المخرج الثاني: حجم البيانات Dataset Size وتوزيع الأنواع

```text
== 1) size of the dataset ==
java    rows  8075  projects  481  tests  7986
python  rows  1618  projects  342  tests  1569
java    top categories: ID 5201, OD 1081, NOD 700, OD-Vic 505, NIO 231, UD 185
python  top categories: OD-Vic 804, OD-Brit 322, NOD 235, NIO 160, OD 54, (none) 39
```

والمخرج يجيب عن السؤال الأول: في Java لدينا 8075 صفاً من 481 مشروعاً، تمثل 7986 اختباراً فريداً، وفي Python لدينا 1618 صفاً من 342 مشروعاً. وهذا حجم كاف لرسالة ماجستير في التصنيف، ولكن لاحظ التوزيع: في Java يسيطر النوع ID بـ 5201 صف، أي أن أغلب الاختبارات المتقلبة المسجلة في Java اكتشفتها أداة NonDex التي تغير ترتيب العناصر في مجموعات مثل HashMap، بينما في Python يسيطر OD-Vic بـ 804\. وهذا ليس بالضرورة توزيع التقلب في العالم، وإنما توزيع ما اكتشفته الأدوات التي استخدمها المساهمون، وهي ملاحظة يجب أن تكتبها في فصل حدود الدراسة Threats to Validity، لأن النموذج الذي يتعلم من هذه البيانات يتعلم ما تراه الأدوات. ولاحظ أيضاً 39 صفاً في Python بلا نوع أصلاً، وقد عرضها البرنامج تحت (none) بدلاً من أن يحذفها بصمت.

### المخرج الثالث: ماذا حدث لطلبات الإصلاح Pull Requests؟

```text
== 2) what happened to the fix PRs (rows with a PR link) ==
java    with PR  4103  accepted/inspired  2454  rejected/won't fix  108  still open  1508  acceptance of decided  95.8%
        statuses: Accepted 2303, Opened 1508, InspiredAFix 151, Rejected 104, DeveloperFixed 33, DeveloperWontFix 4
python  with PR   208  accepted/inspired    74  rejected/won't fix   16  still open   114  acceptance of decided  82.2%
        statuses: Opened 114, Accepted 69, Rejected 11, InspiredAFix 5, DevelopersDoNotWantFix 5, DeveloperFixed 4
```

وهذا القسم يهم فكرتين معاً: فكرة الماجستير إذا أردت أن تضيف إصلاحات حقيقية، وفكرة البكالوريوس الثامنة عن المساهمة في المصادر المفتوحة. ففي Java فتح المساهمون طلبات إصلاح لـ 4103 اختبارات، قبل منها أو ألهم إصلاحاً 2454، ورفض 108، وما زال 1508 مفتوحاً. وإذا حسبنا النسبة من الطلبات التي حسمت فقط، فالقبول 95.8% في Java و82.2% في Python. وهذا رقم مشجع، ولكن اقرأه بحذر لثلاثة أسباب. الأول أن 1508 طلباً، أي أكثر من ثلث الطلبات، لم يحسم أصلاً، فالرفض الصامت، أي الطلب الذي لا يرد عليه أحد، لا يظهر في نسبة القبول. والثاني أن المستودعات المهجورة Unmaintained أو المؤرشفة RepoArchived تخرج من الحساب لأن أحداً لم يفتح فيها طلباً، وهي كثيرة في Python بالذات كما رأينا في توزيع الحالات. والثالث أن Python فيها 208 طلبات فقط مقابل 4103 في Java، فالنسبة فيها أقل ثباتاً.

والدرس العملي لفريق البكالوريوس: إذا اخترت مشروعاً مفتوح المصدر للمساهمة، فلا تنظر إلى نسبة القبول وحدها، وانظر إلى عدد الطلبات المفتوحة دون رد، وإلى آخر Commit في المستودع، وإلى متوسط زمن الرد على طلبات الغرباء. وإذا وجدت أن نصف الطلبات معلقة منذ أشهر فهذا هو الخطر الذي سيقتل مشروعك في الفصل الثاني.

### المخرج الرابع: تركز البيانات Concentration في مشاريع قليلة

```text
== 3) concentration: share of rows in the 10 biggest projects ==
java    top-10 share  33.6%  biggest: alibaba/alibabacloud-tairjedis-sdk (470 rows)
python  top-10 share  33.1%  biggest: eth-cscs/reframe (137 rows)
```

أكبر عشرة مشاريع في Java فيها 33.6% من كل الصفوف، وأكبرها وحده 470 صفاً، وفي Python النسبة قريبة 33.1%. أي أن ثلث البيانات يأتي من عشرة مشاريع من بين مئات. وهذا يعني أن أي نموذج يتدرب على هذه البيانات سوف يرى أسماء الاختبارات وأنماط الكود في هذه المشاريع العشرة أكثر من غيرها، وقد يتعلم «هذا مشروع alibaba، إذن النوع ID» بدلاً من أن يتعلم شيئاً عن التقلب نفسه. وهذه هي المشكلة التي يكشفها القسم التالي بالأرقام.

### المخرج الخامس: خط الأساس Baseline وتسرب البيانات Data Leakage

```text
== 4) baseline: guess the category of a Java flaky test from its name only ==
random 80/20 split      test rows  1589  majority (ID) 0.646  naive bayes 0.837
split by project 80/20  test rows  1941  majority (ID) 0.543  naive bayes 0.360
```

في السطر الأول قسمنا الصفوف عشوائياً 80% للتدريب و20% للاختبار، وهذا ما يفعله أغلب الطلاب لأنه الافتراضي في كل مكتبة. والنتيجة: الفئة الأكثر تكراراً، أي أن تقول ID لكل اختبار، تعطي دقة 0.646، ونموذج Naive Bayes على أسماء الاختبارات يعطي 0.837\. وهذا يبدو تحسناً كبيراً، ولو توقفت هنا لكتبت في الرسالة أن اسم الاختبار يتنبأ بنوع التقلب بدقة 84%.

ولكن في السطر الثاني قسمنا حسب المشروع، أي أن مشاريع الاختبار لم يرها النموذج أبداً في التدريب، وهذا هو الاستخدام الحقيقي، لأن الأداة سوف تستخدم على مشروع جديد. والنتيجة انقلبت: النموذج نزل إلى 0.360، وهو أسوأ من أن تقول ID لكل اختبار، والتي أعطت 0.543\. والسبب أن الاختبارات في نفس المشروع تتشارك كلمات كثيرة في أسمائها، مثل اسم الحزمة واسم الكلاس، فعندما يكون المشروع في التدريب والاختبار معاً، يتعرف النموذج على المشروع، ويعطي نوع أغلب اختباراته. وهذا هو تسرب البيانات Data Leakage: معلومة من الاختبار وصلت إلى التدريب عبر باب جانبي، فظهرت الدقة أعلى مما ستكون عليه في الواقع.

![لوحتان بأعمدة: في التقسيم العشوائي خط الأساس 0.646 والنموذج 0.837، وفي التقسيم حسب المشروع خط الأساس 0.543 والنموذج 0.360 بلون أحمر تحت خط الأساس، وتحت كل لوحة نطاق النتائج في خمس بذور أخرى، وفي الأسفل رسمان صغيران: مشروع تقع اختباراته في التدريب والاختبار معاً، ومشاريع كل منها في جهة واحدة](https://arabroot.io/content/images/2026/11/grad-projects-se-05-leakage.webp)

نفس النموذج ونفس البيانات: 0.837 مع التقسيم العشوائي و0.360 مع التقسيم حسب المشروع

### ماذا يحدث إذا غيرنا البذرة Random Seed؟

قد يقول قائل: ربما كانت النتيجة الثانية حظاً سيئاً، فالمشاريع التي وقعت في الاختبار قد تكون غريبة. والإجابة على ذلك أن نعيد التجربة بخمس بذور مختلفة، وهذا ما يفعله القسم الخامس:

```text
== 5) what if: the same two splits over 5 different seeds ==
seed 0  random: majority 0.663 nb 0.841   by project: majority 0.341 nb 0.392
seed 1  random: majority 0.656 nb 0.836   by project: majority 0.665 nb 0.400
seed 2  random: majority 0.664 nb 0.845   by project: majority 0.617 nb 0.299
seed 3  random: majority 0.649 nb 0.857   by project: majority 0.583 nb 0.350
seed 4  random: majority 0.649 nb 0.850   by project: majority 0.537 nb 0.442
```

في التقسيم العشوائي النتيجة ثابتة تقريباً، فالنموذج بين 0.836 و0.857 في البذور الخمس، والفئة الأكثر تكراراً بين 0.649 و0.664\. أما في التقسيم حسب المشروع فالنموذج بين 0.299 و0.442، وتحت خط الأساس في أربع بذور من خمس، ولكن الأهم أن خط الأساس نفسه يتحرك بين 0.341 و0.665، أي أن نسبة الاختبارات من نوع ID في مشاريع الاختبار تتغير كثيراً حسب أي المشاريع وقعت هناك، والسبب هو التركز الذي رأيناه في القسم السابق، فإذا وقع مشروع فيه 470 صفاً في الاختبار تغير التوزيع كله. والبذرة 0 هي الحالة الوحيدة التي تفوق فيها النموذج على خط الأساس، 0.392 مقابل 0.341، ولكنها حالة كان خط الأساس فيها منخفضاً جداً، وليست دليلاً على أن النموذج تعلم شيئاً.

وماذا يعني هذا لرسالتك؟ يعني ثلاثة قرارات يجب أن تكتبها في المقترح قبل أن تبدأ: أن التقييم سيكون حسب المشروع وليس عشوائياً، وأنك ستعيد التجربة على عدة تقسيمات وتنشر المتوسط والانحراف، وأن خط الأساس الذي يجب أن تتفوق عليه ليس 0.646 كما يبدو في التقسيم العشوائي، وإنما خط أساس يتحرك مع المشاريع ويجب أن تقارن به في كل تقسيم. ويعني أيضاً أن اسم الاختبار وحده لا يكفي، وأن الإضافة الحقيقية في الرسالة يجب أن تأتي من معالم في الكود نفسه، مثل استخدام الوقت أو الحالة المشتركة، وهذا هو سؤال البحث الذي كتبناه في البطاقة. ولو لم نقم بهذه التجربة لبدأ الطالب سنة كاملة على فكرة يظن أن نتيجتها 84%، ثم يكتشف في المناقشة، أو في التحكيم بعدها، أن الرقم كان تسرباً.

## ماذا تقول لك تجربة الجدوى Spike عن أي فكرة؟

ما فعلناه في التجربة ليس خاصاً بالاختبارات المتقلبة، فلكل فكرة في المقال سؤال يمكن أن تجيب عنه في يومين بنفس الطريقة، وهذا ما يجب أن تأخذه إلى المشرف بجانب الأفكار الثلاث:

- مدقق الواجهات العربية: شغل Stylelint بقاعدة واحدة على ثلاثة مستودعات، وعد التنبيهات، وافحص عشرة منها يدوياً، فإذا كان نصفها كاذباً فقد عرفت أين الجهد الحقيقي.
- بلاغات البلدية: شغل خادماً صغيراً يرد على طلب GeoReport واحد، واطلبه من تطبيق عميل موجود، فإذا لم يعمل فقد عرفت أن المعيار أعقد مما في الوثيقة.
- الفوترة الإلكترونية: سجل في بيئة الاختبار وأرسل فاتورة واحدة، فإذا لم تستطع التسجيل في الأسبوع الأول فلا تبن عليها مشروعك.
- المساهمة في المصادر المفتوحة: احسب من سجل المشروع زمن الرد على آخر عشرين طلب دمج من خارج الفريق، كما حسبنا القبول هنا.
- اختبار الطفرات: شغل PIT على خطأ واحد من Defects4J وقس الوقت، ثم اضربه في عدد الأخطاء التي تنوي دراستها.
- اختبار العقود: شغل Train Ticket على جهازك، فإذا لم يعمل في يومين فهذه إجابة.

والقاعدة العامة: تجربة الجدوى تبحث عن سبب لرفض الفكرة، لا عن دليل على نجاحها، والسبب أن الدليل على النجاح يأتي من المشروع كله، أما سبب الرفض فيمكن أن تجده في يومين ويوفر عليك سنة.

## أخطاء شائعة Common Mistakes في اختيار مشروع هندسة البرمجيات

- البدء بالتقنية قبل المشكلة: «نريد مشروعاً بـ Microservices وKubernetes». والتقنية تختار لأنها تحل قيداً في المشكلة، وقد ناقشنا متى تستحق Microservices كلفتها في [دليل Monolith أم Microservices](https://arabroot.io/articles/monolith-%D8%A7%D9%85-microservices-%D9%82%D8%B1%D8%A7%D8%B1-%D8%B5%D8%A7%D8%AF%D9%82-%D9%84%D9%84%D9%81%D8%B1%D9%82-%D8%A7%D9%84%D8%B5%D8%BA%D9%8A%D8%B1%D8%A9-%D9%88%D8%A7%D9%84%D9%83%D8%A8%D9%8A%D8%B1%D8%A9/)، وأغلب مشاريع التخرج لا تحتاجها.
- التقييم بكلمة «جربناه»: اللجنة تريد رقماً، ولو كان بسيطاً، مثل زمن مهمة أو نسبة أخطاء أو مقياس SUS، فاختر المقياس في المقترح، لا في الأسبوع الأخير.
- الاعتماد على جهة خارجية دون خطة بديلة: إذا كانت الفكرة تحتاج بيانات أو واجهة من جهة، فابن بجانبها محاكياً من اليوم الأول، حتى لا يتوقف المشروع إذا تأخرت الجهة.
- نطاق أكبر من الفريق: عشرون شاشة لأربعة طلاب في فصلين تعني أن الاختبارات والتوثيق سوف تكتب في الليلة الأخيرة. والأفضل خمس شاشات مختبرة وموثقة.
- وثيقة متطلبات لا يقرؤها أحد: اكتب المتطلبات في المستودع بجانب الكود، واربطها بالاختبارات، فهكذا تصبح جزءاً من العمل لا ملحقاً في التقرير.
- تقسيم العمل بالطبقات: «أنت الواجهة وأنا الخادم» يجعل كل واحد خبيراً في نصف النظام فقط، وأي سؤال في المناقشة عن النصف الآخر يحرجه. وتقسيم العمل بالميزات يجعل كل واحد يفهم المسار كاملاً.
- في الماجستير: تقسيم البيانات عشوائياً عندما تكون الصفوف مترابطة، كما رأينا في التجربة، أو نشر أفضل نتيجة من عدة تشغيلات بدلاً من المتوسط.
- استخدام الذكاء الاصطناعي في كتابة الكود دون مراجعة: المشرف يرى الكود، واللجنة قد تطلب منك شرح أي سطر، وقد شرحنا كيف تراجع هذا الكود في [دليل مراجعة كود الذكاء الاصطناعي](https://arabroot.io/articles/%D9%85%D8%B1%D8%A7%D8%AC%D8%B9%D8%A9-%D9%83%D9%88%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%AF%D9%88%D9%86-%D8%A7%D9%86-%D8%AA%D8%B5%D8%A8%D8%AD-%D8%B4%D9%83%D9%84%D9%8A%D8%A9/).

## قائمة تحقق Checklist قبل تقديم المقترح

- هل تستطيع أن تشرح المشكلة في جملتين لشخص خارج القسم؟
- هل قابلت مستخدماً حقيقياً واحداً على الأقل، أو حددت من ستقابل في أول أسبوعين؟
- هل فتحت مصدر البيانات بنفسك، ونزلت منه شيئاً، ورأيت حالته؟
- هل كتبت الخطر الذي يقتل الفكرة، وهل اختبرته بتجربة جدوى قصيرة؟
- هل حددت كيف ستقيم المشروع: مقياس، أو دراسة مستخدمين، أو معيار، ومع ماذا ستقارن؟
- هل النطاق مناسب لعدد أعضاء الفريق وفصلين، وهل كتبت ما هو خارج النطاق صراحة؟
- هل هناك معيار خارجي يلتزم به النظام، مثل WCAG أو GeoReport أو مواصفة الفوترة، يجعل التقييم موضوعياً؟
- هل أنشأتم المستودع ونظام المهام من اليوم الأول، كما شرحنا في [دليل Git للمبتدئين](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-%D9%88-git-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)؟
- للماجستير: هل كتبت سؤال البحث، وثلاثة أعمال سابقة قريبة، وخط الأساس، وطريقة تقسيم البيانات؟
- هل في الفكرة شيء ستقوله في المقابلة الوظيفية بعد التخرج غير «بنينا تطبيقاً»؟

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- مشروع هندسة البرمجيات يقيم بالطريقة التي بني بها النظام بقدر ما يقيم بالنظام: متطلبات متتبعة، ومعمارية موثقة، واختبارات، وتقييم بالأرقام.
- البكالوريوس يسأل هل يعمل النظام ويحل مشكلة حقيقية، والماجستير يسأل ما سؤال البحث وما الجديد وكيف قسته مقابل خط أساس.
- تسع أفكار للبكالوريوس بين أدوات الجودة للواجهات العربية والمتطلبات، وأنظمة حقيقية تلتزم بمعايير مثل Open311 والمصرفية المفتوحة والفوترة الإلكترونية، والمساهمة في المصادر المفتوحة وقياس الفريق.
- ست أفكار للماجستير في جودة البرمجيات، كل واحدة على بيانات منشورة: IDoFT وDefects4J وTrain Ticket ومجموعات الدين التقني، ومجموعة عربية تبنيها بنفسك.
- أي فكرة مستهلكة يمكن إنقاذها بقيد حقيقي أو معيار خارجي أو تقييم جاد.
- تجربة الجدوى على IDoFT بينت أن البيانات كافية وتحتاج تنظيفاً، وأن ثلث الصفوف من عشرة مشاريع، وأن نموذجاً بدا بدقة 0.837 نزل إلى 0.360 عندما قسمنا حسب المشروع، أي تحت خط الأساس، وهذا ما كان سيقتل الرسالة لو اكتشف متأخراً.

وإذا لم تختر تخصصك بعد أو تريد أن تفهم لماذا وضعت مواد خطتك، فابدأ من [دليل تخصص هندسة البرمجيات](https://arabroot.io/articles/%D8%AA%D8%AE%D8%B5%D8%B5-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84-%D9%85%D9%86%D9%87%D8%AC-se2014/) ومن [مقارنة التخصصات التقنية](https://arabroot.io/articles/%D8%A7%D9%8A-%D8%AA%D8%AE%D8%B5%D8%B5-%D8%AA%D9%82%D9%86%D9%8A-%D8%AA%D8%AE%D8%AA%D8%A7%D8%B1-%D9%85%D8%A7-%D8%AA%D8%AF%D8%B1%D8%B3%D9%87-%D9%88%D8%A7%D9%8A%D9%86-%D8%AA%D8%B9%D9%85%D9%84/). وأقرب المقالات إلى أفكار هذا المقال على الموقع:

[![](https://arabroot.io/content/images/2026/10/major-se-guide-cover-cover.webp)دليلتخصص هندسة البرمجيات Software Engineering: منهج SE2014ما الذي يجعل المبرمج مهندساً بحسب منهج SE2014 ودليل SWEBOK، وماذا تعطيك خطط الجامعات السعودية منه، وكيف تكمل الباقي بنفسك.](https://arabroot.io/articles/%D8%AA%D8%AE%D8%B5%D8%B5-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D9%85%D9%86-%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84-%D9%85%D9%86%D9%87%D8%AC-se2014/)[![](https://arabroot.io/content/images/2026/10/requirements-engineering-cover-cover.webp)دليلهندسة المتطلبات Requirements Engineering من الطلب إلى ما يبنىما هو المتطلب Requirement، وكيف تجمعه وتكتبه وتراجعه وتدير تغييره، ولماذا تفشل مشاريع كبيرة عندما تهمل هذه الخطوة.](https://arabroot.io/articles/%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D8%AA%D8%B7%D9%84%D8%A8%D8%A7%D8%AA-requirements-engineering/)[![](https://arabroot.io/content/images/2026/10/mutation-testing-cover-cover.webp)دليلاختبار الطفرات Mutation Testing: هل تكشف اختباراتك الأخطاء؟لماذا تمر الأخطاء من اختبارات تغطيتها 100%، وكيف يقيس اختبار الطفرات قوتها فعلاً ويعمل في خط CI دون أن يبطئه.](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%B7%D9%81%D8%B1%D8%A7%D8%AA-mutation-testing/)[![](https://arabroot.io/content/images/2026/10/contract-testing-cover-cover.webp)دليلاختبار العقود Contract Testing بين الخدمات مع Pactكيف تمنع خدمة من تعطيل خدمة أخرى تعتمد عليها قبل النشر، بعقد يكتبه المستهلك ويتحقق منه المزود ويحفظه Pact Broker.](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%B9%D9%82%D9%88%D8%AF-contract-testing-%D9%85%D8%B9-pact/)[![](https://arabroot.io/content/images/2026/10/accessibility-testing-cover-cover.webp)دليلاختبار سهولة الوصول Accessibility لموقع عربيما الذي تجده أدوات فحص سهولة الوصول وما الذي يفوتها، وما الذي يخص المواقع العربية، وكيف تمنع عودة المشاكل في خط CI.](https://arabroot.io/articles/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D9%84%D9%85%D9%88%D9%82%D8%B9-%D8%B9%D8%B1%D8%A8%D9%8A/)[![](https://arabroot.io/content/images/2026/10/i18n-l10n-arabic-cover-cover.webp)دليلالتعريب i18n للمطورين: لماذا ينقلب النص العربي في الواجهة؟لماذا ينقلب النص المختلط في الواجهة العربية وكيف تعزله، وكيف تنسق الأرقام والتواريخ وصيغ الجمع العربية بأدوات المتصفح نفسها.](https://arabroot.io/articles/%D8%A7%D9%84%D8%AA%D8%B9%D8%B1%D9%8A%D8%A8-i18n-%D9%88%D8%A7%D9%84%D9%86%D8%B5-%D8%AB%D9%86%D8%A7%D8%A6%D9%8A-%D8%A7%D9%84%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-bidi-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/clean-architecture-cover-cover.webp)دليلClean Architecture: كيف تعزل منطق العمل عن قاعدة البياناتلماذا تحتاج قاعدة بيانات لكي تختبر قاعدة عمل من سطر واحد، وكيف يعزل اتجاه الاعتماديات منطق العمل عن التفاصيل.](https://arabroot.io/articles/clean-architecture-%D9%88-hexagonal-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF%D9%8A%D8%A7%D8%AA/)[![](https://arabroot.io/content/images/2026/10/oss-governance-cover-cover.webp)دليلمن يدير المشروع مفتوح المصدر؟ نماذج الحوكمة Governanceمن يقرر في مشروع يساهم فيه آلاف الأشخاص، ومن يستطيع تغيير رخصته، وما الذي تفحصه قبل أن تعتمد على أي مشروع.](https://arabroot.io/articles/%D8%AD%D9%88%D9%83%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D9%88%D8%A7%D9%84%D9%85%D8%B3%D8%A7%D9%87%D9%85%D8%A9-%D9%81%D9%8A%D9%87%D8%A7/)

## سجل التحديثات

- نوفمبر 2026: كتابة المقال، والتحقق من كل مصدر بيانات وأداة مذكورة في البطاقات، وتشغيل تجربة الجدوى idoft\_spike.py على Python 3.13 على ملفي IDoFT عند Commit 4903dc9 (قرئ في 1 نوفمبر 2026).