ربط الاختبار

هذه مقدّمة موجزة عن ربط الاختبارات وشرح لكيفية البدء في إعداد الاختبارات في "مشروع Android المفتوح المصدر" (AOSP).

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

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

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

اطّلِع على هذه الأمثلة:

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

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

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

قواعد النصوص البرمجية لإنشاء الحِزم

لكي يتمكّن إطار اختبار اتحاد التجارة من تشغيل وحدات الاختبار لإصدار معيّن، يجب أن تحتوي هذه الوحدات على قيمة 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

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

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

  • يجب ألا يكون لديك أي موفّر إصدار.
  • يجب تنظيفها بعد الانتهاء، مثلاً عن طريق حذف أي ملفات مؤقتة تم إنشاؤها أثناء الاختبار.
  • يجب تغيير إعدادات النظام إلى القيمة التلقائية أو الأصلية.
  • يجب عدم افتراض أنّ الجهاز في حالة معيّنة، مثل أن يكون جاهزًا للوصول إلى الجذر. لا تتطلّب معظم الاختبارات امتيازات الجذر لتنفيذها. إذا كان الاختبار يتطلّب الوصول إلى الجذر، يجب تحديد ذلك باستخدام 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 في الأدلة الرئيسية للمسار الذي تم استيراده. تسمح ميزة &quot;ربط الاختبارات&quot; بعمليات الاستيراد المتداخلة، ما يعني أنّه يمكن لملفّين من النوع TEST_MAPPING استيراد أحدهما للآخر، ويمكن لميزة &quot;ربط الاختبارات&quot; دمج الاختبارات المضمّنة.

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

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

tradefed.sh run commandAndExit [test_module] --help

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

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

لتنفيذ قواعد اختبار ما قبل الإرسال محليًا، اتّبِع الخطوات التالية:

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

    atest
    

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

هذه هي الطريقة الأسهل لتشغيل اختبارات الإرسال المسبق في ملفات TEST_MAPPING في دليل العمل الحالي والأدلة الرئيسية. يبحث Atest عن الملف TEST_MAPPING ويستخدمه في دليل العمل الحالي وجميع الأدلة الرئيسية الخاصة به.

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

يوضّح هذا المثال كيف يمكنك ضبط ملفات 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

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

يمكنك أيضًا استخدام هذا الأمر لتنفيذ قواعد اختبار postsubmit المحدّدة في 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 في دليل العمل الحالي (أو الدليل المحدّد) والأدلة الرئيسية الخاصة به. إذا أردت إجراء الاختبارات في جميع ملفات TEST_MAPPING في الأدلة الفرعية، استخدِم الخيار --include-subdir لإجبار Atest على تضمين هذه الاختبارات أيضًا.

atest --include-subdir

بدون الخيار --include-subdir، لا ينفِّذ Atest سوى الاختبار A. باستخدام الخيار --include-subdir، ينفّذ Atest اختبارَين (أ، ب).

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

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

مثال:

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