اختبار أجهزة متعدّدة

تتوافق تقنية VTS مع الاختبارات التي تتطلّب التفاعل بين عدة أجهزة Android.

هندسة معمارية

يستخدم VTS إطار عمل TradeFed للحصول على الأرقام التسلسلية للأجهزة ونقلها إلى اختبار الوحدات.

الشكل 1: تمرير الأرقام التسلسلية للأجهزة في عملية النقل المرئي للبيانات

يتم تحديد متطلبات الجهاز، مثل عدد الأجهزة وأنواعها، في إعدادات خطة الاختبار. على سبيل المثال، يمكنك تحديد خطة اختبار تتطلّب جهازَي Android مزوّدين بأهداف إنشاء Sailfish.

تخصيص الأجهزة

تخصص البنية الأساسية للاختبار (عادةً جدولة الاختبار) الأجهزة المتاحة التي تستوفي المتطلبات المحدّدة في إعداد خطة الاختبار لإطار عمل VTS. يتم حجز الأجهزة المخصّصة لخطة الاختبار حتى إذا كانت وحدة الاختبار لا تستخدمها. بعد ذلك، يتمّ دفع ملفات ثنائية لوكيل مراقبة الأداء إلى جميع الأجهزة المخصّصة وتشغيلها عليها (ما لم يتمّ توجيهك بعدم تشغيلها). يضمن ذلك توفّر اتصالات بروتوكول النقل المتعدّد (TCP) لأوامر shell وطلبات HAL RPC لجميع الأجهزة في نص اختبار.

جهات إعداد الاختبارات

يشغِّل إطار العمل أدوات إعداد الاختبار لجميع الأجهزة التي تلقّى أرقامها التسلسلية. يمكن أن يكون إعداد الاستهداف على جهاز واحد أو على أجهزة متعددة:

  • أدوات إعداد الاستهداف على جهاز واحد (مثال في VtsDeviceInfoCollector):
    • لا يمكن تحديده إلا في إعداد خطة الاختبار مع قائمة الأجهزة المطلوبة (ستسمح الإصدارات المستقبلية بالضبط على مستوى الوحدة).
    • استلام رقم تسلسلي واحد فقط للجهاز
    • يمكنك تنفيذ مهام الإعداد والتنظيف على جهاز معيّن.
  • أدوات إعداد الأهداف المخصّصة للأجهزة المتعددة (مثال على VtsPythonVirtualenvPreparer):
    • يمكن تحديدها في إعدادات خطة الاختبار أو إعدادات ملف برمجي للاختبار
    • تلقّي جميع الأرقام التسلسلية للأجهزة
    • يمكنك تنفيذ مهام الإعداد والتنظيف لكل جهاز أو لجميع الأجهزة.

وحدات الاختبار

تحصل وحدات الاختبار على قائمة بالأجهزة بعد انتهاء مُعدّي الاختبار من إعداد المضيف/الأجهزة. يتم تشغيل وحدة اختبار Python واحدة من جهة المضيف لكل وحدة اختبار لعدة أجهزة. يمكن الوصول إلى أجهزة Android المخصّصة من وحدات اختبار Python كقائمة بعناصر AndroidDevice:

devices = self.android_devices
device1 = devices[0]
device1_serial = device1.serial

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

تواصل الأجهزة أثناء الاختبار

تتضمن الاختبارات الفعّالة لعدة أجهزة Android التواصل بين الأجهزة المخصّصة. عند تطوير هذه الاختبارات، عليك تحديد كيفية بدء التواصل بين الأجهزة المخصّصة. تقدّم الأقسام التالية ثلاثة أمثلة على رسائل التواصل (ومع ذلك، يحق لمطوّري الاختبارات تصميم نماذج أخرى).

النوع 1: اختبارات HAL من جهة المضيف

يمكن أن تستخدِم اختبارات HAL من جهة المضيف برامج تشغيل HAL لنظام مراقبة الفيديو (VTS) التي يتم دفعها إلى الأجهزة بشكلٍ تلقائي:

الشكل 2: اختبار HAL من جهة المضيف

في هذا السيناريو:

  • يتم تنفيذ منطق الاختبار على المضيف.
  • يُصدر نص الاختبار من جهة المضيف طلبات RPC إلى برامج التشغيل على كل جهاز.
  • تنظّم الجهة المضيف تفاعلات الأجهزة.

النوع 2: الاختبارات المستندة إلى الوكيل من جهة المضيف

بدلاً من استخدام وكلاء فحص الفيديو على الجهاز، يمكن للاختبار من جهة المضيف أيضًا إرسال وكيله (التطبيق أو الملف الثنائي) إلى كل جهاز:

الشكل 3: اختبار مستند إلى الوكيل من جهة المضيف

في هذا السيناريو:

  • يتم تنفيذ منطق الاختبار على المضيف.
  • يتم تثبيت تطبيق "مساعد Google" (أو الملف الثنائي) على كل جهاز.
  • يُصدر نص الاختبار من جهة المضيف أوامر للتطبيقات على كل جهاز.
  • تنظّم الجهة المضيف تفاعلات الأجهزة.

على سبيل المثال، فإنّ اختبارات Next Billion User tests في مستودع VTS الحالي هي اختبارات متعددة الأجهزة ومستندة إلى التطبيق من جهة المضيف.

النوع 3: اختبارات HIDL على الجانب المستهدف

تضع اختبارات HIDL على الجانب المستهدف والمتعددة الأجهزة كل منطق الاختبار في ملفَي برمجيَين لاختبار على جانب الجهاز، ما يتطلّب من الاختبارات مزامنة الأجهزة أثناء تنفيذ الاختبار:

الشكل 4. اختبار HIDL المستند إلى الهدف:

في هذا السيناريو:

  • يتم تنفيذ منطق الاختبار على الأجهزة.
  • يقدّم إطار العمل من جهة المضيف عملية تحديد أولية للجهاز.
  • يتطلب ملف الاختبار الثنائي على الجانب المستهدف المزامنة:
    • ملف الاختبار الثنائي نفسه لجميع الأجهزة
    • وحدات اختبار ثنائية مختلفة لكل دور

مثال: خطة اختبار على أجهزة متعددة

يحدِّد هذا المثال الإعدادات لجهازَين:

  • يتضمّن الجهاز 1 موفِّر الإصدار ومُعدّVtsDeviceInfoCollector الاستهداف.
  • يتضمّن الجهاز 2 أداة إعداد FilePusher إضافية تُرسِل مجموعة من الملفات ذات الصلة التي يتحكم فيها المضيف إلى الجهاز.
<configuration description="VTS Codelab Plan">
  ...
<device name="device1">
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
</device>
<device name="device2" >
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
<option name="push-group" value="HostDrivenTest.push" />
</target_preparer>
</device>
<option name="compatibility:include-filter" value="VtsCodelabHelloWorldMultiDeviceTest" />
</configuration>

مثال: نص برمجي تجريبي بلغة Python من جهة المضيف

لمعرفة التفاصيل والأمثلة حول جهات إعداد الاختبارات، يُرجى الاطّلاع على جهات إعداد الاختبارات. للحصول على مثال كامل على استخدام ميزة "تعدُّد الأجهزة" من جهة المضيف، يمكنك الرجوع إلى hello_world_multi codelab.

def setUpClass(self):
logging.info('number of device: %s', self.android_devices)
asserts.assertEqual(len(self.android_devices), 2, 'number of device is wrong.')
self.dut1 = self.android_devices[0]
self.dut2 = self.android_devices[1]
self.shell1 = self.dut1.shell
self.shell2 = self.dut2.shell

def testSerialNotEqual(self):
'''Checks serial number from two device not being equal.'''
command = 'getprop | grep ro.serial'
res1 = self.shell1.Execute(command)
res2 = self.shell2.Execute(command)

def getSerialFromShellOutput(output):
'''Get serial from getprop query'''
return output[const.STDOUT][0].strip().split(' ')[-1][1:-1]
serial1 = getSerialFromShellOutput(res1)
serial2 = getSerialFromShellOutput(res2)

logging.info('Serial number of device 1 shell output: %s', serial1)
logging.info('Serial number of device 2 shell output: %s', serial2)
asserts.assertNotEqual(serial1, serial2, 'serials from two devices should not be the same')
asserts.assertEqual(serial1, self.dut1.serial, 'serial got from device system property is different from allocated serial')
asserts.assertEqual(serial2, self.dut2.serial, 'serial got from device system property is different from allocated serial')