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

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

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

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

الشكل 1. الأرقام التسلسلية للأجهزة التي اجتازت اختبارات VTS

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

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

تخصّص البنية الأساسية للاختبار (عادةً ما تكون أداة جدولة الاختبار) الأجهزة المتاحة التي تستوفي المتطلبات المحدّدة في إعدادات خطة الاختبار لإطار عمل VTS. تكون الأجهزة المخصّصة محجوزة لخطة الاختبار حتى إذا لم يستخدمها نموذج الاختبار. بعد ذلك، يتم نقل ملفات 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 على الجهاز برامج تشغيل VTS HAL التي يتم إرسالها إلى الأجهزة تلقائيًا:

الشكل 2. اختبار HAL على جانب المضيف

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

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

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

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

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

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

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

على سبيل المثال، اختبارات Next Billion User في مستودع 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 التعليمي.

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')