openQA للمطورين والمشرفين
يستخدم كيدي لينكس openQA لاختبار كل صورة نظام آليًا قبل نشرها. يُقلع openQA كل صورة في آلة افتراضية ويتحقق من إمكانية تثبيتها وترقيتها واستخدامها بنجاح.
لدى openQA بعض المصطلحات المحددة: الوظيفة هي تنفيذ واحد لمجموعة اختبارات ضد صورة، بينما العامل هو الجهاز أو الحاوية التي تشغّل الوظيفة. تشرح وثائق openQA هذه المفاهيم وغيرها، بما في ذلك وحدات الاختبار ومجموعات الوظائف والأصول وواجهة الويب.
كيف تعمل الاختبارات
يعمل عامل الاختبار جنبًا إلى جنب مع خط أنابيب CI، لذا يمكنه استخدام الصور والأقراص الافتراضية المنتجة من البناء دون رفع تلك الملفات الكبيرة إلى مكان آخر. تُقدَّم الاختبارات إلى الآلة الافتراضية عبر امتداد نظام وتتواصل معها عبر SSH.
تستخدم اختبارات سطح المكتب واجهة برمجة إمكانية الوصول عبر selenium-webdriver-at-spi، مما يسمح لها بالتفاعل مع التطبيقات والتحقق من حالتها دون الاعتماد فقط على مطابقة لقطات الشاشة. تتحقق المجموعة أيضًا من خدمات النظام الفاشلة وعمليات سطح المكتب المنهارة ومشاكل الشبكات والانحدارات في أوامر كيدي لينكس.
خط أنابيب CI وسير عمل المشرف
على الفرع الافتراضي المحمي من مستودع كيدي لينكس الرئيسي، يعمل خط الأنابيب على النحو التالي:
- تبني وظيفة التصوير الصورة وقناة sysupdate الخاصة بها وتوقّعها وتجهزها على
storage.kde.org. - تبدأ وظيفة trigger-openqa خط الأنابيب في os-autoinst-distri-kdelinux، وتمرر إليه عنوان URL للصورة المجهزة وعنوان URL لقناة sysupdate.
- يشغّل خط الأنابيب النهائي تدفقي
installوupgradeالمعلنين فيtests/tests.toml، كلٌّ منهما بتثبيت عادي وآخر معمّى. - تعمل وظيفة النشر الرئيسية فقط بعد نجاح خط أنابيب openQA. ترفّع الصورة المجهزة بالفعل للاستهلاك العام.
يجعل هذا فشل openQA بوابة لنشر الصورة. ابدأ بفتح خط الأنابيب النهائي من وظيفة trigger-openqa، ثم افتح وظيفة openQA الفاشلة من سجل CI الخاص بها. تعرض صفحة الوظيفة وحدات الاختبار بالترتيب وتتيح لك تحديد ما إذا كان الفشل في التثبيت أو اختبارات الفحص السليم للنظام المثبت أو مسار الترقية.
نزّل صورة مجهزة
يفتح الرابط المقدَّم بعد رسالة السجل «في حال الفشل، افحص ونزّل الصورة وشجرة sysupdate من…» مستعرض تخزين للبنية قيد الاختبار. نزّل ملف .iso من هناك لإقلاعه يدويًا أو لتسليمه إلى حزمة openQA محلية. تحتوي شجرة sysupdate على نُسخ التحديث المُهيّأة التي يستخدمها اختبار الترقية.
حقق في وظيفة فاشلة
افتح الوظيفة في واجهة ويب openQA وحدد الوحدة الفاشلة أولًا. سيظهر رابط واجهة الويب بعد رسالة السجل “وظيفة اختبار autoinst-log.txt لعامل openQA وسجل محرك الاختبار. هذا هو السجل الأساسي للوظيفة نفسها.
بالنسبة للاختبارات التي تنفذ أوامر على النظام قيد الاختبار، يشغّلها كيدي لينكس في خدمات systemd عابرة ويسجل دفتر يوميات الخدمة كمخرجات تشخيصية في نتيجة الاختبار. افحص autoinst-log.txt لمخرجات الأوامر ودفتر اليوميات. يمكنك أيضًا تنزيل ملف *kde-linux-collected-logs.tar.zst للسجلات الملتقطة بواسطة أداة collect-logs.
شغّل الاختبارات محليًا
يمكنك استخدام openQA لاختبار صورة مبنية محليًا قبل تقديم تغيير. هذا مطلوب عند العمل من نسخة متفرعة خارج kde-linux/kde-linux - يبني خط أنابيب CI الخاص بها صورة اختبار، لكنه لا يشغّل خط أنابيب openQA. وهو مفيد أيضًا أثناء تطوير اختبارات لتغييراتك الخاصة.
يتضمن مستودع اختبارات openQA لكيدي لينكس حزمة محلية تحتوي على واجهة openQA الرسومية وعامل. يتطلب Python 3.14 وPodman وpodman-compose، وكلها مضمنة في كيدي لينكس.
استنسخ مستودع الاختبار، ثم ضع صورة كيدي لينكس .iso التي تريد اختبارها في دليله الجذري. إذا لم تكن هناك صورة، ينزّل مشغل الاختبار أحدث صورة متاحة للعموم بدلًا من ذلك.
ابدأ الحزمة المحلية من جذر المستودع:
./qa-mock up
بعد أن تصبح جاهزة، افتح http://localhost:1080 لفحص واجهة openQA الرسومية. لا تُرسَل المهام آليًا، لذا افتح صدفة في الحاوية وأرسل تدفق install. شغّل أوامر flow وjob وbuild-sysext داخل هذه الحاوية.
./qa-mock enter ./qa flow install
لتشغيل تدفق upgrade بدلًا من ذلك:
./qa flow upgrade
للتثبيت المعمّى، مرّر FDE_INSTALL=1 كإعداد openQA. تميّز لاحقة النوع المهام المعمّاة في الواجهة الرسومية:
./qa flow install --var FDE_INSTALL=1 --flavor-suffix=-encrypted ./qa flow upgrade --var FDE_INSTALL=1 --flavor-suffix=-encrypted
يمكن تكرار --var NAME=VALUE، لكن يجب الإعلان عن كل متغير في قائمة variables الخاصة بالتدفق المحدد في tests/tests.toml.
تستخدم حزمة sanity-test القرص الافتراضي الذي ينشئه install-system. للتركيز على اختبارات معينة، حرّر قائمة tests الخاصة بالحزمة في tests/tests.toml، أو أعلن عن حزمة وتدفق آخرين هناك. يمكنك أيضًا تشغيل حزمة منفردة باستخدام ./qa job --name <suite> مع مراعاة تبعيات القرص الخاصة بها. تقبل أوامر flow وjob وbuild-sysext الخيار --manifest-path <path> لاستخدام بيان غير tests/tests.toml. مسارات الاختبارات داخل البيان نسبية إلى دليل ذلك البيان. شغّل ./qa job --help لمعرفة خياراته المطلوبة.
على سبيل المثال، ابنِ امتداد النظام وشغّل مهمة install-system مع ملف .iso في دليل المستودع. استبدل معرّف البنية والنسخة بمعرّفي صورتك:
./qa build-sysext
./qa job \
--live ./kde-linux_<build-id>.iso \
--hdd kde-linux_<build-id>.qcow2 \
--sysext ./openqa-sysext.img \
--build <build-id> \
--variant <variant> \
--name install-system \
--flavor live
عند الانتهاء، اخرج من صدفة الحاوية، ثم أوقف الحزمة وأزل أحجامها المحلية من المضيف.
./qa-mock down -v
يمرّر ./qa-mock الوسائط إلى podman-compose. على سبيل المثال، استخدم ./qa-mock up -d لبدء الحزمة في الخلفية.
اختبر الترقيات بين البنيات المحلية
ضع ملف ISO الأساسي في جذر مستودع الاختبار. عند بدء الحزمة من المضيف، اضبط KDE_LINUX_OUTPUT على دليل mkosi.output الذي يحتوي على البنية التي تريد الترقية إليها:
KDE_LINUX_OUTPUT=~/Repositories/kde-linux/mkosi.output ./qa-mock up
ادخل إلى الحاوية وشغّل تدفق الترقية، مع استبدال <build-id> بمعرّف بنية ملف ISO الأساسي:
./qa-mock enter
./qa flow upgrade \
--upgrade-from /casedir/kde-linux_<build-id>.iso \
--upgrade-to /kde-linux-output
يجب توفير الخيارين معًا. يُوصَل المستودع عند /casedir، ويُوصَل دليل mkosi.output المحدد للقراءة فقط عند /kde-linux-output. تُقدَّم أحدث بنية في ذلك الدليل إلى الآلة الافتراضية كمصدر sysupdate مؤقت ويجب أن تكون أحدث من ملف ISO الأساسي. أضف --var FDE_INSTALL=1 --flavor-suffix=-encrypted لاختبار تثبيت معمّى.
أعلن عن الحزم والتدفقات
يعرّف tests/tests.toml التوزيعة (name وdistri) والحزم والتدفقات. الحزمة قائمة مرتبة من الاختبارات تُشغَّل في مهمة openQA واحدة. يحدد action الخاص بها كيفية استخدام المهمة للقرص الافتراضي:
- يُقلع
installالصورة الحية وينشئ القرص المثبَّت. - يُقلع
upgradeالقرص المثبَّت ويضبطDO_UPGRADEللاختبارات التي تنفذ الترقية. - يُقلع
testالقرص المثبَّت للتحقق.
يشغّل التدفق الحزم بالترتيب المعلن، ويمرّر القرص المثبَّت بين المهام. يعرّف كيدي لينكس هذه التدفقات:
[flows.install] suites = ["install-system", "sanity-test"] variables = ["FDE_INSTALL"] [flows.upgrade] suites = ["install-system", "upgrade-system", "sanity-test"] variables = ["FDE_INSTALL"]
يثبّت تدفق install البنية قيد الاختبار ويفحصها. يثبّت تدفق upgrade أولًا صورة أقدم، ويرقّيها إلى البنية قيد الاختبار، ثم يشغّل اختبارات السلامة. بالنسبة لبنية CI مُهيّأة، يكون الأساس أحدث صورة منشورة. بدون --upgrade-from و--upgrade-to، ستستخدم عملية ترقية محلية أحدث بنية عامة كهدف لها مبدئيًا، باستخدام ملف ISO محلي أقدم إن وُجد أو بتنزيل الصورة السابقة.
قبل كل مهمة، يولّد العامل دليل اختبار مؤقتًا (CASEDIR) مع جدول main.pm للحزمة المحددة. تُشغَّل الاختبارات بترتيب البيان، بما في ذلك الإدخالات المتكررة. حرّر البيان لتغيير الجدول.
اكتب اختبارًا
توجد تعريفات الاختبارات وشيفرتها في os-autoinst-distri-kdelinux. أضف نصوص الاختبارات تحت tests/، إلى جانب الاختبارات ذات الصلة، وسجّلها في مصفوفة tests الخاصة بالحزمة المناسبة في tests/tests.toml. على سبيل المثال:
[suites.example]
action = "test"
tests = [
{ path = "common/bootup.py", type = "openqa" },
{ path = "common/basic_test.py", type = "python" },
{ path = "kdelinux/app/firefox.py", type = "selenium", user = "installed", timeout = 180 },
]
تُنفَّذ اختبارات openqa على العامل وتستخدم واجهات openQA مباشرة. تُنفَّذ اختبارات python وselenium على النظام قيد الاختبار، ويحزم امتداد النظام نصوصها آليًا، ويولّد العامل أغلفة اختبارات openQA التي تستدعيها.
اختر نوع الاختبار بناءً على ما تفحصه:
- استخدم
unittestبايثون عاديًا لأدوات سطر الأوامر، أو الخدمات، أو حالة نظام الملفات، أو أي سلوك غير رسومي آخر. - استخدم Selenium عبر
selenium-webdriver-at-spiعندما يتطلب السلوك التفاعل مع تطبيق رسومي.
اختبارات بايثون العادية
أنشئ unittest تحت tests/، على سبيل المثال tests/kdelinux/system/example.py. ينبغي أن يقدّم تأكيدات حول النظام قيد الاختبار ويكتب نتائجه في ملف JUnit XML، الذي سيُجمَع آليًا كأصل openQA وتقرير GitLab CI.
import unittest
from lib.sut import openqa_junit_xml
class ExampleTests(unittest.TestCase):
def test_expected_behaviour(self):
self.assertTrue(True)
if __name__ == "__main__":
openqa_junit_xml.run(ExampleTests, "example")
أضف إدخالًا إلى مصفوفة tests الخاصة بالحزمة ذات الصلة:
{ path = "kdelinux/system/example.py", type = "python" },
يجمع الغلاف المولَّد نتيجة JUnit ومخرجات الأمر بحيث تظهر الإخفاقات في مهمة openQA ومخرجات CI.
الاختبارات الرسومية مع Selenium
الاختبارات الرسومية هي أيضًا أصناف unittest بايثون، لكنها تستخدم برنامج تشغيل Appium/Selenium للعثور على عناصر واجهة المستخدم القابلة للوصول والتفاعل معها. مفعّل Selenium يشغّل البنية التحتية لإمكانية الوصول ويبدأ برنامج التشغيل نيابةً عنك.
على سبيل المثال، ينشئ اختبار رسومي برنامج تشغيل لتطبيقه، ويتفاعل مع العناصر القابلة للوصول، ويغلق برنامج التشغيل بعد ذلك:
import unittest
from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from lib.sut import openqa_junit_xml
class ExampleTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
options = AppiumOptions()
options.set_capability("app", "org.kde.example.desktop")
cls.driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def test_expected_behaviour(self):
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "example-control").click()
if __name__ == "__main__":
openqa_junit_xml.run(ExampleTests, "example")
احفظ النص باسم، على سبيل المثال، tests/kdelinux/app/example.py، وأضفه إلى الحزمة ذات الصلة مع type = "selenium". اختر مستخدم الاختبار المثبَّت لتطبيقات سطح المكتب:
{ path = "kdelinux/app/example.py", type = "selenium", user = "installed", timeout = 180 },
شغّل التدفق الذي يحتوي على حزمتك محليًا أثناء تطويرها.
خيارات الاختبار والأغلفة المخصصة
بالنسبة لأغلفة SUT المولَّدة، يمكن لإدخالات البيان ضبط user (root أو live أو installed أو plasma_setup)، وtimeout بالثواني (القيمة المبدئية 90)، وartifacts كقائمة مسارات لجمعها، وعلامتي openQA fatal = true أو always_run = true. اضبط enabled = false لإبقاء اختبار معلنًا مع استبعاده من الجدول.
عندما يحتاج اختبار إلى شكل من أشكال التنسيق المخصص ليعمل، ضع غلافًا بجانب نص SUT الخاص به وأشر إليه باستخدام override:
{ path = "kdelinux/system/collect_logs.py", type = "selenium", override = "kdelinux/system/collect_logs.openqa.py" },
هذا الغلاف المخصص مسؤول عن علاماته ومستخدمه ومهلة انتظاره وجمع مخرجاته، ويجب أن يمرّر المسار النسبي لنص SUT إلى CliTest.run_python() أو CliTest.run_selenium(). انظر إلى collect_logs.openqa.py الموجود للحصول على مثال.
لمزيد من المعلومات حول كتابة اختبارات Selenium، راجع اختبار الأتمتة Appium واختبار الواجهة الرسومية مع selenium-webdriver-at-spi.
تعلّم المزيد
لشرح أكثر تفصيلًا لتدفق الاختبار وتنفيذه، راجع اختبار openQA في كيدي لينكس. تُطوَّر البنية التحتية للاختبار في مستودع os-autoinst-distri-kdelinux.
المقالة مساهمة من Thomas Duckworth تحت ترخيص CC-BY-4.0.