כתיבת בדיקה מבוססת-מארח ב-Trade Federation

בדף הזה מוסבר איך לכתוב בדיקת מכשיר בסגנון JUnit4 שמבוססת על המארח. המשמעות היא שהצד המארח של ה-harness יפעיל פעולות במכשיר.

חשוב לשים לב שאנחנו רואים הבדל קל בין בדיקות בצד המארח לבין בדיקות שמבוססות על המארח:

  • בדיקה שמבוססת על המארח: בדיקה שמופעלת במארח ומתקשרת עם מכשיר אחד או יותר. המערכת שנבדקת (SUT) לא נמצאת במארח עצמו, אלא נבדקת מהמארח.
  • בדיקה בצד המארח: בדיקה שמופעלת רק במארח ובודקת משהו רק במארח, לדוגמה בדיקות יחידה.

למה כדאי ליצור בדיקה שמבוססת על מארח ולא בדיקת מכשור?

בבדיקות מסוימות יכול להיות שתצטרכו להשפיע על המצב הכולל של המכשיר, למשל להנפיק פקודה להפעלה מחדש. בתרחיש הבדיקה של אינסטרומנטציה, הפעלה מחדש תגרום להפסקת האינסטרומנטציה, הבדיקה לא תוכל להימשך ולא יהיו תוצאות זמינות.

בדיקות שמבוססות על המארח יכולות גם להפעיל שלבי הגדרה נוספים שדורשים אינטראקציה עם מכשירים חיצוניים שהבדיקה תלויה בהם.

בדיקה שמבוססת על המארח יכולה לטפל בתרחישי השימוש האלה ולאפשר בדיקה מתקדמת של המכשיר עם תרחישים נוספים. אם זה המצב, הכי הגיוני לכתוב בדיקה שמבוססת על המארח.

איך כותבים ב-TF בדיקות שמבוססות על המארח?

לדוגמה:

@RunWith(DeviceJUnit4ClassRunner.class)
public class SampleHostJUnit4DeviceTest extends BaseHostJUnit4Test {
    @Before
    public void setUp() throws Exception {
       // Some setup
    }

    @Test
    public void testCheckWeHaveDevice() throws Exception {
        Assert.assertNotNull(getDevice());
    }
}

בדיקות שמופעלות על ידי המארח ב-Trade Federation מופעלות על ידי DeviceJUnit4ClassRunner JUnit4 test runner. המבנה הכולל של מחלקת הבדיקה זהה למבנה של בדיקת JUnit4 רגילה:

  • @BeforeClass
  • @Before
  • @Test
  • @After
  • @AfterClass
  • Assume, Assert

הרחבה של BaseHostJunit4Test היא דרך להעביר בירושה API של כלי בדיקה שימושיים, כמו:

  • installPackage: מאפשר להתקין קובץ APK במכשיר היעד.
  • installPackageAsUser: מאפשר להתקין קובץ APK כמשתמש במכשיר היעד.
  • uninstallPackage: מאפשר להסיר APK.
  • isPackageInstalled: בדיקה אם חבילה מותקנת או לא.
  • hasDeviceFeature: בדיקה אם המכשיר תומך בתכונה מסוימת. (pm list features)
  • runDeviceTests(DeviceTestRunOptions options): מריצים בדיקת מכשור (instrumentation) במכשיר היעד באמצעות DeviceTestRunOptions כדי לטפל בכל האפשרויות האפשריות.

צריך גם לספק גישה לאובייקט המכשיר Tradefed:

  • getDevice(): מחזירה אובייקט של מכשיר TF לצורך מניפולציה של המכשיר.
  • getBuild(): מחזירה אובייקט TF של פרטי גרסה כדי לקבל מידע על הגרסה.
  • getAbi(): מחזירה את ה-ABI שהבדיקה פועלת מולו.

תמיכה ב-Tradefed: הכנה וניקוי של מכשירים לפי מחלקה

‫JUnit4 @BeforeClass ו-@AfterClass רלוונטיים רק לשיטות סטטיות, ולכן אי אפשר להשתמש ב-handler‏ #getDevice() כדי לבצע הגדרה או ניקוי חד-פעמיים שספציפיים למכשיר לכל מחלקה. כדי לפתור את הבעיה, צריך להשתמש בהערה Tradefed.

  • ‫@BeforeClassWithInfo: מופעל לפני ההערות ‎ @BeforeClass
  • ‫‎@AfterClassWithInfo: מופעל אחרי הערות ‎ @AfterClass
   @BeforeClassWithInfo
   public static void beforeClassWithDevice(TestInformation testInfo) {
       assertNotNull(testInfo.getDevice());
       testInfo.properties().put("mytest:test-prop", "test");
   }

   @AfterClassWithInfo
   public static void afterClassWithDevice(TestInformation testInfo) {
       assertNotNull(testInfo.getDevice());
       testInfo.properties().put("mytest:test-prop", "test");
   }

TestInformation מאפשר לכם להשתמש במכשיר ולאחסן מאפיינים שאפשר להשתמש בהם בהיקף סטטי או לא סטטי. ‫BaseHostJUnit4Test תומך בקבלת TestInformation בהיקף שאינו סטטי באמצעות #getTestInformation().

אם אתם לא משתמשים ב-BaseHostJUnit4Test, אתם יכולים להטמיע את ITestInformationReceiver כדי לקבל את אובייקט TestInformation.

איך מגדירים בדיקה מבוססת-מארח ב-Tradefed?

בקובץ ההגדרות של Tradefed XML, בדיקות שמבוססות על המארח מופעלות באמצעות רכיב ה-runner‏ HostTest.

<test class="com.android.tradefed.testtype.HostTest" >
    <option name="class" value="android.sample.cts.SampleHostJUnit4DeviceTest" />
</test>