ربط الاختبار

هذه مقدّمة موجزة عن ربط الاختبارات وشرح لكيفية بدء ضبط الاختبارات في مشروع Android Open Source Project ‏ (AOSP).

لمحة عن ربط الاختبارات

ربط الاختبار هو نهج يستند إلى Gerrit يتيح للمطوّرين إنشاء قواعد اختبار ما قبل الإرسال وما بعد الإرسال مباشرةً في شجرة مصدر Android وترك قرارات الفروع والأجهزة التي سيتم اختبارها للبنية الأساسية للاختبار. تعريفات ربط الاختبارات هي ملفات JSON باسم TEST_MAPPING يمكنك وضعها في أي دليل مصدر.

يمكن أن يستخدم Atest ملفات TEST_MAPPING لإجراء اختبارات ما قبل الإرسال في الدلائل المرتبطة. باستخدام ميزة "ربط الاختبارات"، يمكنك إضافة المجموعة نفسها من الاختبارات إلى عمليات التحقّق من التقديم المُسبَق مع إجراء تغيير بسيط داخل شجرة مصدر Android.

راجِع هذه الأمثلة:

يعتمد ربط الاختبارات على مجموعة أدوات اختبار Trade Federation (TF) ل ejecutang الاختبارات وإعداد تقارير النتائج.

تحديد مجموعات الاختبار

اختبِر مجموعات الربط باستخدام مجموعة اختبار. يمكن أن يكون اسم مجموعة الاختبار أي سلسلة. على سبيل المثال، يمكن أن يكون presubmit اسمًا لمجموعة من الاختبارات التي يتم إجراؤها عند التحقّق من التغييرات. ويمكن أن تكون postsubmit هي الاختبارات المستخدَمة للتحقّق من صحة الإصدارات بعد دمج التغييرات.

قواعد نص إنشاء الحِزم

لكي يتمكّن برنامج اختبار Trade Federation من تشغيل وحدات اختبار لإصدار معيّن، يجب أن تحتوي هذه الوحدات على test_suites تم ضبطه على Soong أو LOCAL_COMPATIBILITY_SUITE تم ضبطه على Make في إحدى الحزمتَين التاليتَين:

  • general-tests مخصّص للاختبارات التي لا تعتمد على ميزات خاصة بالجهاز (مثل الأجهزة الخاصة بالمورّد والتي لا تملكها معظم الأجهزة). يجب أن تكون معظم الاختبارات في مجموعة general-tests، حتى إذا كانت مخصّصة لبنية ABI أو عدد بتات أو ميزات أجهزة معيّنة، مثل HWASan (تتوفّر استهداف test_suites منفصل لكل بنية ABI)، وحتى إذا كان يجب إجراؤها على جهاز.
  • device-tests مخصّص للاختبارات التي تعتمد على الإمكانات الخاصة بالجهاز. يمكن العثور على هذه الاختبارات عادةً ضمن vendor/. يشير التصنيف خاص بالجهاز فقط إلى الإمكانات الفريدة لجهاز معيّن، لذا ينطبق ذلك على اختبارات JUnit واختبارات GTest (التي يجب وضع علامة عليها عادةً باستخدامgeneral-tests حتى إذا كانت خاصة بواجهة برمجة التطبيقات).

أمثلة:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

ضبط الاختبارات لتشغيلها في مجموعة اختبارات

لكي يتم تشغيل اختبار داخل مجموعة اختبارات، يجب أن يستوفي الاختبار الشروط التالية:

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

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

إنشاء ملفات ربط اختبارية

بالنسبة إلى الدليل الذي يتطلّب تغطية اختبار، أضِف TEST_MAPPING ملف JSON يشبه المثال. تضمن هذه القواعد إجراء الاختبارات في عمليات التحقّق من التقديم المُسبَق عند تعديل أي ملفات في هذا الدليل أو أي من المجلدات الفرعية.

اتّباع مثال

في ما يلي نموذج لملف TEST_MAPPING (بتنسيق JSON مع تعليقات متوافقة):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

ضبط السمات

في المثال، presubmit وpostsubmit هما اسما كل مجموعة اختبار. اطّلِع على تحديد مجموعات الاختبار للحصول على مزيد من المعلومات عن مجموعات الاختبار.

يمكنك ضبط اسم وحدة الاختبار أو اسم اختبار دمج Trade Federation (مسار المورد إلى ملف XML للاختبار، على سبيل المثال، uiautomator/uiautomator-demo) في قيمة السمة name. يُرجى العِلم أنّ حقل name لا يمكنه استخدام الفئة name أو طريقة الاختبار name. لتضييق نطاق الاختبارات التي سيتم إجراؤها، استخدِم خيارات مثل include-filter. اطّلِع على include-filter نموذج الاستخدام.

يشير إعداد host للاختبار إلى ما إذا كان الاختبار اختبارًا بدون جهاز يُجريه المضيف أم لا. القيمة التلقائية هي false، ما يعني أنّ الاختبار يتطلب جهازًا لتنفيذه. أنواع الاختبارات المتوافقة هي HostGTest لملفّات GTest الثنائية وHostTest لاختبارات JUnit.

تتيح لك السمة file_patterns ضبط قائمة بسلاسل التعبيرات العادية لمطابقة المسار النسبي لأي ملف رمز مصدر (بالنسبة إلى المجلد الذي يحتوي على ملف TEST_MAPPING). في المثال، لا يتم تنفيذ الاختبار CtsWindowManagerDeviceTestCases في مرحلة ما قبل الإرسال إلا عندما يبدأ ملف Java برمز Window أو Activity، والذي يكون متوفّرًا في الدليل نفسه الذي يتضمّن ملف TEST_MAPPING أو أيًا من الدلائل الفرعية له. يجب ترميز الشرطة المائلة للخلف (\) لأنّها موجودة في ملف JSON.

تتيح لك سمة imports تضمين الاختبارات في ملفات TEST_MAPPING أخرى بدون نسخ المحتوى. يتم أيضًا تضمين ملفات TEST_MAPPING في المجلدات الرئيسية للمسار المستورَد. يسمح ربط الاختبار بعمليات الاستيراد المُدمجة، ما يعني أنّه يمكن لملفَّي TEST_MAPPING استيراد بعضهما، ويمكن لميزة ربط الاختبار دمج الاختبارات المضمّنة.

تحتوي السمة options على خيارات إضافية لسطر أوامر Tradefed.

للحصول على قائمة كاملة بالخيارات المتاحة لاختبار معيّن، يمكنك تنفيذ:

tradefed.sh run commandAndExit [test_module] --help

راجِع معالجة الخيارات في Tradefed للحصول على مزيد من التفاصيل حول آلية عمل الخيارات.

إجراء الاختبارات باستخدام Atest

لتنفيذ قواعد اختبار التقديم المُسبَق محليًا:

  1. انتقِل إلى الدليل الذي يحتوي على ملف TEST_MAPPING.
  2. شغِّل الأمر:

    atest
    

يتم تشغيل جميع اختبارات الفحص قبل الإرسال التي تم ضبطها في ملفات TEST_MAPPING الخاصة بالملف الجاري العرض والمجلدات الرئيسية له. يحدِّد Atest موقع اختبارَين ويُجريهما للإرسال المُسبَق (أ و ب).

هذه هي الطريقة الأكثر وضوحًا لإجراء اختبارات الفحص قبل الإرسال في TEST_MAPPING الملفات في الدليل الحالي للعمل (CWD) والأدلة الرئيسية. يحدِّد الإجراء Atest موقع ملف TEST_MAPPING ويستخدمه في CWD وجميع أدلة الملفّات الرئيسية.

بنية رمز المصدر

يوضّح هذا المثال كيفية ضبط ملفات TEST_MAPPING في شجرة المصدر:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

محتوى src/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

محتوى src/project_1/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

محتوى src/project_2/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

تحديد الأدلة المستهدَفة

يمكنك تحديد دليل مستهدف لإجراء الاختبارات في ملفات TEST_MAPPING في ذلك الدليل. يُجري الأمر التالي اختبارَين (أ، ب):

atest --test-mapping src/project_1

تنفيذ قواعد اختبار ما بعد الإرسال

يمكنك أيضًا استخدام هذا الأمر لتشغيل قواعد اختبار ما بعد الإرسال المحدّدة فيملف ‎ TEST_MAPPING في src_path (الإعداد التلقائي هو CWD) والملفات التوجيهية الرئيسية:

atest [--test-mapping] [src_path]:postsubmit

إجراء الاختبارات التي لا تتطلّب استخدام أي جهاز فقط

يمكنك استخدام الخيار --host لتطبيق Atest لتشغيل الاختبارات التي تم ضبطها فقط ضد المضيف التي لا تتطلّب أي جهاز. بدون هذا الخيار، يُجري Atest كلاً من الاختبارات، تلك التي تتطلّب جهازًا وتلك التي يتم إجراؤها على مضيف لا يتطلّب جهازًا. يتم إجراء الاختبارات في مجموعتَين من الاختبارات المنفصلتَين:

atest [--test-mapping] --host

تحديد مجموعات الاختبار

يمكنك تحديد مجموعات الاختبار في الأمر Atest. يُنفِّذ الأمر التالي جميع اختبارات postsubmit ذات الصلة بالملفات في الدليل src/project_1، والذي يحتوي بدوره على اختبار واحد فقط (C).

أو يمكنك استخدام :all لإجراء جميع الاختبارات بغض النظر عن المجموعة. يُجري الرمز التالي أربعة اختبارات (A وB وC وX):

atest --test-mapping src/project_1:all

تضمين الأدلة الفرعية

يؤدي تشغيل الاختبارات في TEST_MAPPING باستخدام Atest تلقائيًا إلى تنفيذ اختبارات ما قبل الإرسال فقط التي تم ضبطها في ملف TEST_MAPPING في CWD (أو الدليل المحدّد) والمجلدات الرئيسية. إذا كنت تريد إجراء اختبارات في جميعملفّات TEST_MAPPING في الأدلة الفرعية، استخدِم الخيار --include-subdir لفرض تضمين Atest لهذه الاختبارات أيضًا.

atest --include-subdir

بدون الخيار --include-subdir، لا يُجري Atest سوى الاختبار "أ". باستخدام الخيار --include-subdir، يُجري Atest اختبارَين (أ، ب).

التعليقات على مستوى السطر متاحة

يمكنك إضافة تعليق // بتنسيق على مستوى السطر لتوضيح TEST_MAPPINGملف مع وصف للإعداد الذي يليه. ATest وTrade Federation يُجريان معالجة مسبقة لملف TEST_MAPPING إلى تنسيق JSON صالح بدون تعليقات. للحفاظ على تنسيق ملف JSON مرتبًا، لا يُسمح إلا بتعليقات // بتنسيق سطر واحد.

مثال:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}