استهدف مثال التطبيق

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

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

يستخدم هذا الدليل الاختبار التالي ليكون بمثابة عينة:

  • الأطر / القاعدة / الحزم / شل / الاختبارات

يوصى بتصفح الكود أولاً للحصول على انطباع تقريبي قبل المتابعة.

اتخاذ قرار بشأن موقع المصدر

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

اطلع على المزيد من المناقشات حول موقع المصدر في المثال الشامل لاختبارات القياس الذاتي .

ملف البيان

تمامًا مثل التطبيق العادي، تحتاج كل وحدة اختبار للأجهزة إلى ملف بيان. إذا قمت بتسمية الملف باسم AndroidManifest.xml وقمت بتوفيره بجوار Android.mk لاختبار tmodule الخاص بك، فسيتم تضمينه تلقائيًا بواسطة ملف makefile الأساسي BUILD_PACKAGE .

قبل المتابعة، يوصى بشدة بالاطلاع على نظرة عامة على بيان التطبيق أولاً.

يقدم هذا نظرة عامة على المكونات الأساسية لملف البيان ووظائفها.

يمكن الوصول إلى أحدث إصدار من ملف البيان لنموذج تغيير gerrit على: https://android.googlesource.com/platform/frameworks/base/+/main/packages/Shell/tests/AndroidManifest.xml

يتم تضمين لقطة هنا للراحة:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

    <application>
        <uses-library android:name="android.test.runner" />

        <activity
            android:name="com.android.shell.ActionSendMultipleConsumerActivity"
            android:label="ActionSendMultipleConsumer"
            android:theme="@android:style/Theme.NoDisplay"
            android:noHistory="true"
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.shell"
        android:label="Tests for Shell" />

</manifest>

حدد البعض الملاحظات في ملف البيان:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.shell.tests">

سمة package هي اسم حزمة التطبيق: هذا هو المعرف الفريد الذي يستخدمه إطار عمل تطبيق Android لتحديد التطبيق (أو في هذا السياق: تطبيق الاختبار الخاص بك). يمكن لكل مستخدم في النظام تثبيت تطبيق واحد فقط يحمل اسم الحزمة هذا.

نظرًا لأن هذه حزمة تطبيق اختبارية، ومستقلة عن حزمة التطبيق قيد الاختبار، فيجب استخدام اسم حزمة مختلف: إحدى القواعد الشائعة هي إضافة لاحقة .test .

علاوة على ذلك، فإن سمة package هذه هي نفسها التي تُرجعها ComponentName#getPackageName() ، وهي أيضًا نفس السمة التي ستستخدمها للتفاعل مع مختلف أوامر pm الفرعية عبر adb shell .

يرجى أيضًا ملاحظة أنه على الرغم من أن اسم الحزمة عادةً ما يكون بنفس نمط اسم حزمة Java، إلا أنه في الواقع يحتوي على عدد قليل جدًا من الأشياء التي تتعلق به. بمعنى آخر، قد تحتوي حزمة تطبيقك (أو اختبارك) على فئات بأي أسماء حزم، على الرغم من أنه من ناحية أخرى، يمكنك اختيار البساطة وأن يكون اسم حزمة Java ذات المستوى الأعلى في تطبيقك أو اختبارك مطابقًا لاسم حزمة التطبيق.

<uses-library android:name="android.test.runner" />

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

android:targetPackage="com.android.shell"

يؤدي هذا إلى تعيين الحزمة المستهدفة للأجهزة على com.android.shell . عندما يتم استدعاء الأجهزة عبر أمر am instrument ، يقوم إطار العمل بإعادة تشغيل عملية com.android.shell ، ويدخل رمز الأجهزة في العملية لتنفيذ الاختبار. وهذا يعني أيضًا أن كود الاختبار سيكون له حق الوصول إلى جميع مثيلات الفئة التي تعمل في التطبيق قيد الاختبار وقد يكون قادرًا على معالجة الحالة اعتمادًا على خطافات الاختبار المكشوفة.

ملف التكوين البسيط

يجب أن تحتوي كل وحدة اختبار جديدة على ملف تكوين لتوجيه نظام الإنشاء باستخدام البيانات التعريفية للوحدة وتبعيات وقت الترجمة وتعليمات التعبئة. في معظم الحالات، يكون خيار ملف Blueprint المستند إلى Soong كافيًا. راجع تكوين الاختبار البسيط للحصول على التفاصيل.

ملف التكوين المعقد

بالنسبة للاختبارات الأكثر تعقيدًا، تحتاج أيضًا إلى كتابة ملف تكوين اختباري لأداة اختبار Android، Trade Union .

يمكن لتكوين الاختبار تحديد خيارات إعداد الجهاز الخاصة والوسائط الافتراضية لتوفير فئة الاختبار.

يمكن الوصول إلى أحدث إصدار من ملف التكوين لنموذج تغيير gerrit على: Frameworks/base/packages/Shell/tests/AndroidTest.xml

يتم تضمين لقطة هنا للراحة:

<configuration description="Runs Tests for Shell.">
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="ShellTests.apk" />
    </target_preparer>

    <option name="test-suite-tag" value="apct" />
    <option name="test-tag" value="ShellTests" />
    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.shell.tests" />
        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
    </test>
</configuration>

حدد بعض الملاحظات على ملف تكوين الاختبار:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="ShellTests.apk"/>
</target_preparer>

هذا يخبر الاتحاد التجاري بتثبيت ShellTests.apk على الجهاز المستهدف باستخدام target_preparer المحدد. هناك العديد من أدوات إعداد الأهداف المتاحة للمطورين في الاتحاد التجاري ويمكن استخدامها لضمان إعداد الجهاز بشكل صحيح قبل تنفيذ الاختبار.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="com.android.shell.tests"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

يحدد هذا فئة اختبار الاتحاد التجاري المراد استخدامه لتنفيذ الاختبار ويمرر في الحزمة الموجودة على الجهاز المراد تنفيذه وإطار تشغيل الاختبار الذي هو JUnit في هذه الحالة.

انظر هنا لمزيد من المعلومات حول تكوينات وحدة الاختبار

مميزات JUnit4

يتيح استخدام مكتبة android-support-test كمشغل اختبار اعتماد فئات اختبار نمط JUnit4 الجديدة، ويحتوي نموذج تغيير gerrit على بعض الاستخدامات الأساسية جدًا لميزاته.

يمكن الوصول إلى أحدث كود مصدر لنموذج تغيير gerrit على: Frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

على الرغم من أن أنماط الاختبار تكون عادةً خاصة بالفرق المكونة، إلا أن هناك بعض أنماط الاستخدام المفيدة بشكل عام.

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

هناك اختلاف كبير في JUnit4 وهو أن الاختبارات لم تعد مطلوبة للوراثة من فئة اختبار أساسية مشتركة؛ بدلاً من ذلك، يمكنك كتابة الاختبارات في فئات Java العادية واستخدام التعليقات التوضيحية للإشارة إلى إعدادات وقيود معينة للاختبار. في هذا المثال، نطلب منك تشغيل هذه الفئة كاختبار Android JUnit4.

حدد التعليق @SmallTest حجم اختبار لفئة الاختبار بأكملها: جميع طرق الاختبار المضافة إلى فئة الاختبار هذه ترث هذا التعليق التوضيحي لحجم الاختبار. إعداد فئة الاختبار المسبق، وتمزيق ما بعد الاختبار، وتمزيق فئة ما بعد الاختبار: على غرار أساليب setUp و tearDown في JUnit4. يتم استخدام التعليق Test لتعليق الاختبار الفعلي.

    @Before
    public void setup() {
    ...
    @Test
    public void testGetProvider_shouldCacheProvider() {
    ...

يتم استخدام التعليق التوضيحي @Before في الطرق بواسطة JUnit4 لإجراء إعداد الاختبار المسبق. على الرغم من عدم استخدامه في هذا المثال، هناك أيضًا @After لتفكيك ما بعد الاختبار. وبالمثل، يمكن استخدام التعليقات التوضيحية @BeforeClass و @AfterClass في الطرق بواسطة JUnit4 لإجراء الإعداد قبل تنفيذ جميع الاختبارات في فئة الاختبار، والتفكيك بعد ذلك. لاحظ أن أساليب الإعداد والتفكيك لنطاق الفصل يجب أن تكون ثابتة.

أما بالنسبة لطرق الاختبار، على عكس الإصدار السابق من JUnit، فإنها لم تعد بحاجة إلى بدء اسم الطريقة بـ test ، وبدلاً من ذلك، يجب إضافة تعليق توضيحي لكل منها بـ @Test . كالعادة، يجب أن تكون طرق الاختبار عامة، ولا تعلن عن قيمة إرجاع، ولا تأخذ أي معلمات، وقد تطرح استثناءات.

        Context context = InstrumentationRegistry.getTargetContext();

نظرًا لأن اختبارات JUnit4 لم تعد تتطلب فئة أساسية شائعة، لم يعد من الضروري الحصول على مثيلات Context عبر getContext() أو getTargetContext() عبر أساليب الفئة الأساسية؛ بدلاً من ذلك، يقوم مشغل الاختبار الجديد بإدارتها عبر InstrumentationRegistry حيث يتم تخزين الإعداد السياقي والبيئي الذي تم إنشاؤه بواسطة إطار عمل الأجهزة. من خلال هذا الفصل يمكنك أيضًا الاتصال بـ:

  • getInstrumentation() : مثيل لفئة Instrumentation
  • getArguments() : تم تمرير وسيطات سطر الأوامر إلى am instrument عبر -e <key> <value>

بناء واختبار محليا

بالنسبة لحالات الاستخدام الأكثر شيوعًا، استخدم Atest .

بالنسبة للحالات الأكثر تعقيدًا التي تتطلب تخصيصًا أكبر، اتبع تعليمات الأجهزة .