آزمایش نقشه برداری

این مقدمه‌ای کوتاه بر نگاشت تست و توضیحی در مورد نحوه شروع پیکربندی تست‌ها در پروژه متن‌باز اندروید (AOSP) است.

درباره نقشه برداری تست

نگاشت تست یک رویکرد مبتنی بر Gerrit است که به توسعه‌دهندگان اجازه می‌دهد قوانین تست presubmit و postsubmit را مستقیماً در درخت منبع اندروید ایجاد کنند و تصمیم‌گیری در مورد شاخه‌ها و دستگاه‌هایی که باید آزمایش شوند را به زیرساخت تست واگذار کنند. تعاریف نگاشت تست، فایل‌های JSON با نام TEST_MAPPING هستند که می‌توانید آنها را در هر دایرکتوری منبع قرار دهید.

Atest می‌تواند از فایل‌های TEST_MAPPING برای اجرای تست‌های presubmit در دایرکتوری‌های مرتبط استفاده کند. با استفاده از نگاشت تست، می‌توانید همان مجموعه تست‌ها را برای بررسی‌های presubmit با حداقل تغییر در درخت منبع اندروید اضافه کنید.

این مثال‌ها را ببینید:

نگاشت تست برای اجرای تست‌ها و گزارش نتایج به مهار تست فدراسیون تجارت (TF) متکی است.

تعریف گروه‌های آزمایشی

نگاشت تست، تست‌ها را با یک گروه تست گروه‌بندی می‌کند. نام یک گروه تست می‌تواند هر رشته‌ای باشد. برای مثال، presubmit می‌تواند نام گروهی از تست‌ها باشد که هنگام اعتبارسنجی تغییرات اجرا می‌شوند. و postsubmit می‌تواند تست‌هایی باشد که برای اعتبارسنجی ساخت‌ها پس از ادغام تغییرات استفاده می‌شوند.

قوانین اسکریپت ساخت بسته

برای اینکه تست هارنس فدراسیون تجارت بتواند ماژول‌های آزمایشی را برای یک ساخت مشخص اجرا کند، این ماژول‌ها باید یک مجموعه test_suites برای Soong یا یک مجموعه LOCAL_COMPATIBILITY_SUITE برای Make به یکی از این دو مجموعه داشته باشند:

  • general-tests برای تست‌هایی است که به قابلیت‌های خاص دستگاه وابسته نیستند (مانند سخت‌افزار مخصوص فروشنده که اکثر دستگاه‌ها آن را ندارند). اکثر تست‌ها باید در مجموعه general-tests باشند، حتی اگر مختص یک ABI یا bitness یا ویژگی‌های سخت‌افزاری مانند HWASan باشند (برای هر ABI یک هدف test_suites جداگانه وجود دارد)، و حتی اگر مجبور باشند روی یک دستگاه اجرا شوند.
  • device-tests برای تست‌هایی است که به قابلیت‌های خاص دستگاه بستگی دارند. معمولاً این تست‌ها در vendor/ یافت می‌شوند. Device-specific فقط به قابلیت‌هایی اشاره دارد که مختص یک دستگاه هستند، بنابراین این موضوع هم در مورد تست‌های JUnit و هم در مورد تست‌های GTest صدق می‌کند (که معمولاً باید به عنوان general-tests علامت‌گذاری شوند، حتی اگر مختص ABI باشند).

مثال‌ها:

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

می‌توانید نام ماژول آزمایشی یا نام آزمون یکپارچه‌سازی فدراسیون تجاری (مسیر منبع به فایل XML آزمایشی، برای مثال، uiautomator/uiautomator-demo ) را در مقدار ویژگی name تنظیم کنید. توجه داشته باشید که فیلد name نمی‌تواند از name کلاس یا name متد آزمایشی استفاده کند. برای محدود کردن تست‌های قابل اجرا، از گزینه‌هایی مانند include-filter استفاده کنید. به include-filter sample usage مراجعه کنید.

تنظیم host یک تست نشان می‌دهد که آیا تست، یک تست بدون دستگاه است که روی میزبان اجرا می‌شود یا خیر. مقدار پیش‌فرض false است، به این معنی که تست برای اجرا به یک دستگاه نیاز دارد. انواع تست پشتیبانی‌شده عبارتند از HostGTest برای باینری‌های GTest و HostTest برای تست‌های JUnit.

ویژگی file_patterns به شما امکان می‌دهد لیستی از رشته‌های عبارات منظم را برای تطبیق مسیر نسبی هر فایل کد منبع (نسبت به دایرکتوری حاوی فایل TEST_MAPPING ) تنظیم کنید. در مثال ، test CtsWindowManagerDeviceTestCases فقط زمانی در presubmit اجرا می‌شود که یک فایل جاوا با Window یا Activity شروع شود، که در همان دایرکتوری فایل TEST_MAPPING یا هر یک از زیرشاخه‌های آن وجود دارد. علامت‌های \ (بک‌اسلش) باید escape شوند زیرا در یک فایل JSON هستند.

ویژگی imports به شما امکان می‌دهد تست‌ها را بدون کپی کردن محتوا، در سایر فایل‌های TEST_MAPPING وارد کنید. فایل‌های TEST_MAPPING موجود در دایرکتوری‌های والد مسیر وارد شده نیز شامل می‌شوند. نگاشت تست امکان ایمپورت‌های تو در تو را فراهم می‌کند؛ این بدان معناست که دو فایل TEST_MAPPING می‌توانند یکدیگر را وارد کنند و نگاشت تست می‌تواند تست‌های وارد شده را ادغام کند.

ویژگی options شامل گزینه‌های خط فرمان اضافی Tradefed است.

برای دریافت لیست کاملی از گزینه‌های موجود برای یک آزمون مشخص، دستور زیر را اجرا کنید:

tradefed.sh run commandAndExit [test_module] --help

برای جزئیات بیشتر در مورد نحوه عملکرد آپشن‌ها، به بخش مدیریت آپشن‌ها در Tradefed مراجعه کنید.

اجرای تست‌ها با Atest

برای اجرای قوانین تست presubmit به صورت محلی:

  1. به دایرکتوری حاوی فایل TEST_MAPPING بروید.
  2. دستور زیر را اجرا کنید:

    atest
    

تمام تست‌های presubmit که در فایل‌های TEST_MAPPING دایرکتوری فعلی و دایرکتوری‌های والد آن پیکربندی شده‌اند، اجرا می‌شوند. Atest دو تست برای presubmit (A و B) را پیدا کرده و اجرا می‌کند.

این ساده‌ترین راه برای اجرای تست‌های پیش از ارسال در فایل‌های TEST_MAPPING در دایرکتوری کاری فعلی (CWD) و دایرکتوری‌های والد است. Atest فایل TEST_MAPPING را در CWD و تمام دایرکتوری‌های والد آن پیدا کرده و از آن استفاده می‌کند.

ساختار کد منبع

این مثال نشان می‌دهد که چگونه می‌توانید فایل‌های 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 در آن دایرکتوری مشخص کنید. دستور زیر دو تست (A، B) را اجرا می‌کند:

atest --test-mapping src/project_1

اجرای قوانین تست ارسال پست

همچنین می‌توانید از این دستور برای اجرای قوانین تست ارسال پست که در 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 فقط تست‌های presubmit پیکربندی شده در فایل TEST_MAPPING در CWD (یا دایرکتوری داده شده) و دایرکتوری‌های والد آن را اجرا می‌کند. اگر می‌خواهید تست‌ها را در تمام فایل‌های TEST_MAPPING در زیر دایرکتوری‌ها اجرا کنید، از گزینه --include-subdir برای مجبور کردن Atest به شامل کردن آن تست‌ها نیز استفاده کنید.

atest --include-subdir

بدون گزینه --include-subdir ، Atest فقط تست A را اجرا می‌کند. با گزینه --include-subdir ، Atest دو تست (A، B) را اجرا می‌کند.

پشتیبانی از کامنت در سطح خط

می‌توانید یک کامنت // format در سطح خط اضافه کنید تا فایل TEST_MAPPING را به همراه توضیحی از تنظیماتی که در ادامه می‌آید، تکمیل کنید. فدراسیون ATest and Trade، TEST_MAPPING بدون کامنت، به فرمت JSON معتبر پیش‌پردازش می‌کند. برای تمیز نگه داشتن فایل JSON، فقط کامنت // format در سطح خط پشتیبانی می‌شود.

مثال:

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