یک مثال برنامه را هدف قرار دهید

این دسته از تست‌های ابزار دقیق با تست‌هایی که برنامه‌های معمولی اندروید را هدف قرار می‌دهند، تفاوتی ندارد. شایان ذکر است که برنامه آزمایشی شامل ابزار دقیق باید با همان گواهینامه برنامه مورد نظر امضا شود.

توجه داشته باشید که این راهنما فرض می‌کند که شما قبلاً دانشی در مورد گردش کار درخت منبع پلت فرم دارید. اگر نه، لطفاً به الزامات مراجعه کنید. مثالی که در اینجا به آن پرداخته می‌شود، نوشتن یک تست ابزار دقیق با بسته هدف در بسته برنامه آزمایشی خودش است. اگر با مفهوم آشنا نیستید، لطفاً مقدمه تست پلتفرم را بخوانید.

این راهنما از آزمون زیر به عنوان نمونه استفاده می کند:

  • چارچوب/پایه/بسته/شل/تست

توصیه می‌شود قبل از ادامه، ابتدا کد را مرور کنید تا تصوری نادرست داشته باشید.

در مورد مکان منبع تصمیم بگیرید

از آنجایی که تست ابزار دقیق یک برنامه کاربردی را هدف قرار می دهد، قرارداد این است که کد منبع آزمایشی را در فهرستی tests در زیر ریشه دایرکتوری منبع جزء خود در درخت منبع پلت فرم قرار دهید.

بحث‌های بیشتر درباره مکان منبع را در مثال سرتاسری برای تست‌های خود ابزار دقیق ببینید.

فایل مانیفست

درست مانند یک برنامه معمولی، هر ماژول تست ابزار دقیق نیاز به یک فایل مانیفست دارد. اگر فایل را AndroidManifest.xml نامگذاری کنید و آن را در کنار Android.mk برای ماژول آزمایشی خود ارائه دهید، به طور خودکار توسط فایل اصلی BUILD_PACKAGE اضافه می شود.

قبل از ادامه، به شدت توصیه می‌شود ابتدا نمای کلی مانیفست برنامه را مرور کنید.

این یک نمای کلی از اجزای اصلی یک فایل مانیفست و عملکردهای آنها را ارائه می دهد.

آخرین نسخه فایل مانیفست برای نمونه تغییر گریت را می توان در آدرس زیر مشاهده کرد: 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 استفاده می کنید.

لطفاً همچنین توجه داشته باشید که اگرچه نام بسته معمولاً به سبک نام بسته جاوا است، اما در واقع موارد بسیار کمی با آن انجام می شود. به عبارت دیگر، بسته برنامه (یا آزمایش) شما ممکن است شامل کلاس هایی با هر نام بسته باشد، اگرچه از طرف دیگر، می توانید سادگی را انتخاب کنید و نام بسته جاوای سطح بالای خود را در برنامه یا تست خود با نام بسته برنامه یکسان داشته باشید.

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

این برای تمام تست‌های ابزار دقیق مورد نیاز است زیرا کلاس‌های مرتبط در یک فایل کتابخانه jar Framework جداگانه بسته‌بندی می‌شوند، بنابراین زمانی که بسته آزمایشی توسط چارچوب برنامه فراخوانی می‌شود، به ورودی‌های مسیر کلاس اضافی نیاز دارد.

android:targetPackage="com.android.shell"

این بسته هدف ابزار دقیق را روی com.android.shell تنظیم می کند. هنگامی که ابزار دقیق از طریق دستور am instrument فراخوانی می شود، فریم ورک فرآیند com.android.shell را مجدداً راه اندازی می کند و کد ابزار دقیق را برای اجرای آزمایش به فرآیند تزریق می کند. این همچنین به این معنی است که کد تست به تمام نمونه های کلاس در حال اجرا در برنامه تحت آزمایش دسترسی خواهد داشت و ممکن است بتواند وضعیت را بسته به قلاب های آزمایشی در معرض نمایش قرار دهد.

فایل پیکربندی ساده

هر ماژول آزمایشی جدید باید یک فایل پیکربندی برای هدایت سیستم ساخت با فراداده های ماژول، وابستگی های زمان کامپایل و دستورالعمل های بسته بندی داشته باشد. در بیشتر موارد، گزینه فایل Blueprint مبتنی بر Soong کافی است. برای جزئیات بیشتر به پیکربندی تست ساده مراجعه کنید.

فایل پیکربندی پیچیده

برای آزمایش‌های پیچیده‌تر، همچنین باید یک فایل پیکربندی آزمایشی برای مهار تست اندروید، Trade Federation بنویسید.

پیکربندی تست می‌تواند گزینه‌های راه‌اندازی دستگاه خاص و آرگومان‌های پیش‌فرض را برای تامین کلاس تست مشخص کند.

آخرین نسخه فایل پیکربندی برای تغییر نمونه 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>

این به Trade Federation می گوید که 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>

این کلاس تست Trade Federation را مشخص می‌کند تا از آن برای اجرای تست استفاده شود و در بسته روی دستگاهی که باید اجرا شود و چارچوب تست runner که در این مورد JUnit است را پاس می‌کند.

برای اطلاعات بیشتر در مورد تنظیمات ماژول تست اینجا را ببینید

ویژگی های JUnit4

استفاده از کتابخانه android-support-test به عنوان اجرای آزمایشی، پذیرش کلاس‌های تست سبک JUnit4 جدید را امکان‌پذیر می‌سازد، و نمونه تغییر گریت حاوی برخی استفاده‌های بسیار اساسی از ویژگی‌های آن است.

آخرین کد منبع برای تغییر نمونه گریت را می توان در آدرس زیر مشاهده کرد: Frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

در حالی که الگوهای آزمایشی معمولاً مختص تیم های جزء هستند، برخی از الگوهای استفاده به طور کلی مفید هستند.

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

یک تفاوت قابل توجه در JUnit4 این است که دیگر نیازی به ارث بردن از یک کلاس تست پایه مشترک نیست. در عوض، تست‌ها را در کلاس‌های جاوا ساده می‌نویسید و از حاشیه‌نویسی برای نشان دادن تنظیمات و محدودیت‌های تست خاص استفاده می‌کنید. در این مثال، ما دستور می دهیم که این کلاس باید به عنوان یک تست 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() : آرگومان های خط فرمان از طریق -e <key> <value> به am instrument ارسال می شود.

به صورت محلی بسازید و آزمایش کنید

برای رایج ترین موارد استفاده، از Atest استفاده کنید.

برای موارد پیچیده‌تر که نیاز به سفارشی‌سازی سنگین‌تر دارند، دستورالعمل‌های ابزار دقیق را دنبال کنید.

،

این دسته از تست‌های ابزار دقیق با تست‌هایی که برنامه‌های معمولی اندروید را هدف قرار می‌دهند، تفاوتی ندارد. شایان ذکر است که برنامه آزمایشی شامل ابزار دقیق باید با همان گواهینامه برنامه مورد نظر امضا شود.

توجه داشته باشید که این راهنما فرض می‌کند که شما قبلاً دانشی در مورد گردش کار درخت منبع پلت فرم دارید. اگر نه، لطفاً به الزامات مراجعه کنید. مثالی که در اینجا به آن پرداخته می‌شود، نوشتن یک تست ابزار دقیق با بسته هدف در بسته برنامه آزمایشی خودش است. اگر با مفهوم آشنا نیستید، لطفاً مقدمه تست پلتفرم را بخوانید.

این راهنما از آزمون زیر به عنوان نمونه استفاده می کند:

  • چارچوب/پایه/بسته/شل/تست

توصیه می‌شود قبل از ادامه، ابتدا کد را مرور کنید تا تصوری نادرست داشته باشید.

در مورد مکان منبع تصمیم بگیرید

از آنجایی که تست ابزار دقیق یک برنامه کاربردی را هدف قرار می دهد، قرارداد این است که کد منبع آزمایشی را در فهرستی tests در زیر ریشه دایرکتوری منبع جزء خود در درخت منبع پلت فرم قرار دهید.

بحث‌های بیشتر درباره مکان منبع را در مثال سرتاسری برای تست‌های خود ابزار دقیق ببینید.

فایل مانیفست

درست مانند یک برنامه معمولی، هر ماژول تست ابزار دقیق نیاز به یک فایل مانیفست دارد. اگر فایل را AndroidManifest.xml نامگذاری کنید و آن را در کنار Android.mk برای ماژول آزمایشی خود ارائه دهید، به طور خودکار توسط فایل اصلی BUILD_PACKAGE اضافه می شود.

قبل از ادامه، به شدت توصیه می‌شود ابتدا نمای کلی مانیفست برنامه را مرور کنید.

این یک نمای کلی از اجزای اصلی یک فایل مانیفست و عملکردهای آنها را ارائه می دهد.

آخرین نسخه فایل مانیفست برای نمونه تغییر گریت را می توان در آدرس زیر مشاهده کرد: 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 استفاده می کنید.

لطفاً همچنین توجه داشته باشید که اگرچه نام بسته معمولاً به سبک نام بسته جاوا است، اما در واقع موارد بسیار کمی با آن انجام می شود. به عبارت دیگر، بسته برنامه (یا آزمایش) شما ممکن است شامل کلاس هایی با هر نام بسته باشد، اگرچه از طرف دیگر، می توانید سادگی را انتخاب کنید و نام بسته جاوای سطح بالای خود را در برنامه یا تست خود با نام بسته برنامه یکسان داشته باشید.

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

این برای تمام تست‌های ابزار دقیق مورد نیاز است زیرا کلاس‌های مرتبط در یک فایل کتابخانه jar Framework جداگانه بسته‌بندی می‌شوند، بنابراین زمانی که بسته آزمایشی توسط چارچوب برنامه فراخوانی می‌شود، به ورودی‌های مسیر کلاس اضافی نیاز دارد.

android:targetPackage="com.android.shell"

این بسته هدف ابزار دقیق را روی com.android.shell تنظیم می کند. هنگامی که ابزار دقیق از طریق دستور am instrument فراخوانی می شود، فریم ورک فرآیند com.android.shell را مجدداً راه اندازی می کند و کد ابزار دقیق را برای اجرای آزمایش به فرآیند تزریق می کند. این همچنین به این معنی است که کد تست به تمام نمونه های کلاس در حال اجرا در برنامه تحت آزمایش دسترسی خواهد داشت و ممکن است بتواند وضعیت را بسته به قلاب های آزمایشی در معرض نمایش قرار دهد.

فایل پیکربندی ساده

هر ماژول آزمایشی جدید باید یک فایل پیکربندی برای هدایت سیستم ساخت با فراداده های ماژول، وابستگی های زمان کامپایل و دستورالعمل های بسته بندی داشته باشد. در بیشتر موارد، گزینه فایل Blueprint مبتنی بر Soong کافی است. برای جزئیات بیشتر به پیکربندی تست ساده مراجعه کنید.

فایل پیکربندی پیچیده

برای آزمایش‌های پیچیده‌تر، همچنین باید یک فایل پیکربندی آزمایشی برای مهار تست اندروید، Trade Federation بنویسید.

پیکربندی تست می‌تواند گزینه‌های راه‌اندازی دستگاه خاص و آرگومان‌های پیش‌فرض را برای تامین کلاس تست مشخص کند.

آخرین نسخه فایل پیکربندی برای تغییر نمونه 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>

این به Trade Federation می گوید که 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>

این کلاس تست Trade Federation را مشخص می‌کند تا از آن برای اجرای تست استفاده شود و در بسته روی دستگاهی که باید اجرا شود و چارچوب تست runner که در این مورد JUnit است را پاس می‌کند.

برای اطلاعات بیشتر در مورد تنظیمات ماژول تست اینجا را ببینید

ویژگی های JUnit4

استفاده از کتابخانه android-support-test به عنوان اجرای آزمایشی، پذیرش کلاس‌های تست سبک JUnit4 جدید را امکان‌پذیر می‌سازد، و نمونه تغییر گریت حاوی برخی استفاده‌های بسیار اساسی از ویژگی‌های آن است.

آخرین کد منبع برای تغییر نمونه گریت را می توان در آدرس زیر مشاهده کرد: Frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

در حالی که الگوهای آزمایشی معمولاً مختص تیم های جزء هستند، برخی از الگوهای استفاده به طور کلی مفید هستند.

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

یک تفاوت قابل توجه در JUnit4 این است که دیگر نیازی به ارث بردن از یک کلاس تست پایه مشترک نیست. در عوض، تست‌ها را در کلاس‌های جاوا ساده می‌نویسید و از حاشیه‌نویسی برای نشان دادن تنظیمات و محدودیت‌های تست خاص استفاده می‌کنید. در این مثال، ما دستور می دهیم که این کلاس باید به عنوان یک تست 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() : آرگومان های خط فرمان از طریق -e <key> <value> به am instrument ارسال می شود.

به صورت محلی بسازید و آزمایش کنید

برای رایج ترین موارد استفاده، از Atest استفاده کنید.

برای موارد پیچیده‌تر که نیاز به سفارشی‌سازی سنگین‌تر دارند، دستورالعمل‌های ابزار دقیق را دنبال کنید.

،

این دسته از تست‌های ابزار دقیق با تست‌هایی که برنامه‌های معمولی اندروید را هدف قرار می‌دهند، تفاوتی ندارد. شایان ذکر است که برنامه آزمایشی شامل ابزار دقیق باید با همان گواهینامه برنامه مورد نظر امضا شود.

توجه داشته باشید که این راهنما فرض می‌کند که شما قبلاً دانشی در مورد گردش کار درخت منبع پلت فرم دارید. اگر نه، لطفاً به الزامات مراجعه کنید. مثالی که در اینجا به آن پرداخته می‌شود، نوشتن یک تست ابزار دقیق با بسته هدف در بسته برنامه آزمایشی خودش است. اگر با مفهوم آشنا نیستید، لطفاً مقدمه تست پلتفرم را بخوانید.

این راهنما از آزمون زیر به عنوان نمونه استفاده می کند:

  • چارچوب/پایه/بسته/شل/تست

توصیه می‌شود قبل از ادامه، ابتدا کد را مرور کنید تا تصوری نادرست داشته باشید.

در مورد مکان منبع تصمیم بگیرید

از آنجایی که تست ابزار دقیق یک برنامه کاربردی را هدف قرار می دهد، قرارداد این است که کد منبع آزمایشی را در فهرستی tests در زیر ریشه دایرکتوری منبع جزء خود در درخت منبع پلت فرم قرار دهید.

بحث‌های بیشتر درباره مکان منبع را در مثال سرتاسری برای تست‌های خود ابزار دقیق ببینید.

فایل مانیفست

درست مانند یک برنامه معمولی، هر ماژول تست ابزار دقیق نیاز به یک فایل مانیفست دارد. اگر فایل را AndroidManifest.xml نامگذاری کنید و آن را در کنار Android.mk برای ماژول آزمایشی خود ارائه دهید، به طور خودکار توسط فایل اصلی BUILD_PACKAGE اضافه می شود.

قبل از ادامه، به شدت توصیه می‌شود ابتدا نمای کلی مانیفست برنامه را مرور کنید.

این یک نمای کلی از اجزای اصلی یک فایل مانیفست و عملکردهای آنها را ارائه می دهد.

آخرین نسخه فایل مانیفست برای نمونه تغییر گریت را می توان در آدرس زیر مشاهده کرد: 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 استفاده می کنید.

لطفاً همچنین توجه داشته باشید که اگرچه نام بسته معمولاً به سبک نام بسته جاوا است، اما در واقع موارد بسیار کمی با آن انجام می شود. به عبارت دیگر، بسته برنامه (یا آزمایش) شما ممکن است شامل کلاس هایی با هر نام بسته باشد، اگرچه از طرف دیگر، می توانید سادگی را انتخاب کنید و نام بسته جاوای سطح بالای خود را در برنامه یا تست خود با نام بسته برنامه یکسان داشته باشید.

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

این برای تمام تست‌های ابزار دقیق مورد نیاز است زیرا کلاس‌های مرتبط در یک فایل کتابخانه jar Framework جداگانه بسته‌بندی می‌شوند، بنابراین زمانی که بسته آزمایشی توسط چارچوب برنامه فراخوانی می‌شود، به ورودی‌های مسیر کلاس اضافی نیاز دارد.

android:targetPackage="com.android.shell"

این بسته هدف ابزار دقیق را روی com.android.shell تنظیم می کند. هنگامی که ابزار دقیق از طریق دستور am instrument فراخوانی می شود، فریم ورک فرآیند com.android.shell را مجدداً راه اندازی می کند و کد ابزار دقیق را برای اجرای آزمایش به فرآیند تزریق می کند. این همچنین به این معنی است که کد تست به تمام نمونه های کلاس در حال اجرا در برنامه تحت آزمایش دسترسی خواهد داشت و ممکن است بتواند وضعیت را بسته به قلاب های آزمایشی در معرض نمایش قرار دهد.

فایل پیکربندی ساده

هر ماژول آزمایشی جدید باید یک فایل پیکربندی برای هدایت سیستم ساخت با فراداده های ماژول، وابستگی های زمان کامپایل و دستورالعمل های بسته بندی داشته باشد. در بیشتر موارد، گزینه فایل Blueprint مبتنی بر Soong کافی است. برای جزئیات بیشتر به پیکربندی تست ساده مراجعه کنید.

فایل پیکربندی پیچیده

برای آزمایش‌های پیچیده‌تر، همچنین باید یک فایل پیکربندی آزمایشی برای مهار تست اندروید، Trade Federation بنویسید.

پیکربندی تست می‌تواند گزینه‌های راه‌اندازی دستگاه خاص و آرگومان‌های پیش‌فرض را برای تامین کلاس تست مشخص کند.

آخرین نسخه فایل پیکربندی برای تغییر نمونه 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>

این به Trade Federation می گوید که 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>

این کلاس تست Trade Federation را مشخص می‌کند تا از آن برای اجرای تست استفاده شود و در بسته روی دستگاهی که باید اجرا شود و چارچوب تست runner که در این مورد JUnit است را پاس می‌کند.

برای اطلاعات بیشتر در مورد تنظیمات ماژول تست اینجا را ببینید

ویژگی های JUnit4

استفاده از کتابخانه android-support-test به عنوان اجرای آزمایشی، پذیرش کلاس‌های تست سبک JUnit4 جدید را امکان‌پذیر می‌سازد، و نمونه تغییر گریت حاوی برخی استفاده‌های بسیار اساسی از ویژگی‌های آن است.

آخرین کد منبع برای تغییر نمونه گریت را می توان در آدرس زیر مشاهده کرد: Frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

در حالی که الگوهای آزمایشی معمولاً مختص تیم های جزء هستند، برخی از الگوهای استفاده به طور کلی مفید هستند.

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

یک تفاوت قابل توجه در JUnit4 این است که دیگر نیازی به ارث بردن از یک کلاس تست پایه مشترک نیست. در عوض، تست‌ها را در کلاس‌های جاوا ساده می‌نویسید و از حاشیه‌نویسی برای نشان دادن تنظیمات و محدودیت‌های تست خاص استفاده می‌کنید. در این مثال، ما دستور می دهیم که این کلاس باید به عنوان یک تست 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() : آرگومان های خط فرمان از طریق -e <key> <value> به am instrument ارسال می شود.

به صورت محلی بسازید و آزمایش کنید

برای رایج ترین موارد استفاده، از Atest استفاده کنید.

برای موارد پیچیده‌تر که نیاز به سفارشی‌سازی سنگین‌تر دارند، دستورالعمل‌های ابزار دقیق را دنبال کنید.