מיפוי בדיקות

כאן נספק מבוא קצר למיפוי בדיקות, ונסביר איך מתחילים להגדיר בדיקות בפרויקט Android Open Source Project‏ (AOSP).

מידע על מיפוי בדיקות

מיפוי בדיקות הוא גישה שמבוססת על Gerrit ומאפשרת למפתחים ליצור כללי בדיקה לפני שליחת בקשת תיקון (presubmit) ואחרי שליחת בקשת תיקון (postsubmit) ישירות בעץ המקור של Android, ולהשאיר את ההחלטות לגבי ההסתעפויות והמכשירים לבדיקה לתשתית הבדיקה. הגדרות למיפוי בדיקות הן קובצי JSON בשם TEST_MAPPING שאפשר למקם בכל ספריית מקור.

Atest יכול להשתמש בקבצים TEST_MAPPING כדי להריץ בדיקות לפני שליחת הקוד לתיקיות המשויכות. בעזרת מיפוי בדיקות, אפשר להוסיף את אותה קבוצת בדיקות לבדיקות המקדימות לשליחת בקשות תיקון, עם שינוי מינימלי בעץ המקור של Android.

דוגמאות:

מיפוי הבדיקות מסתמך על ערכת בדיקות של Trade Federation‏ (TF) להרצת בדיקות ולדיווח על תוצאות.

הגדרת קבוצות בדיקה

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

כללים של סקריפט build לחבילות

כדי שTrade Federation test harness יוכל להריץ מודולים של בדיקה לגרסה נתונה של build, צריך להגדיר למודולים האלה את הערך test_suites עבור Soong או את הערך LOCAL_COMPATIBILITY_SUITE עבור Make לאחת משתי חבילות הבדיקה הבאות:

  • general-tests מיועד לבדיקות שלא תלויות ביכולות ספציפיות למכשיר (כמו חומרה ספציפית לספק שאין ברוב המכשירים). רוב הבדיקות צריכות להיות בחבילת general-tests, גם אם הן ספציפיות ל-ABI אחד או לגודל בייט אחד או לתכונות חומרה כמו HWASan (יש יעד test_suites נפרד לכל ABI), וגם אם הן צריכות לפעול במכשיר.
  • device-tests מיועד לבדיקות שתלויות ביכולות ספציפיות למכשיר. בדרך כלל הבדיקות האלה נמצאות בקטע vendor/. Device-specific (ספציפי למכשיר) מתייחס רק ליכולות ייחודיות למכשיר, כך שההגדרה הזו רלוונטית לבדיקות JUnit וגם לבדיקות GTest (בדרך כלל צריך לסמן אותן בתווית general-tests גם אם הן ספציפיות ל-ABI).

לדוגמה:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

הגדרת בדיקות להרצה בחבילת בדיקות

כדי שבדיקה תרוץ בתוך חבילת בדיקות, היא צריכה:

  • אסור שיהיה לו ספק build.
  • צריך לנקות אחרי שהבדיקה מסתיימת, למשל על ידי מחיקה של קבצים זמניים שנוצרו במהלך הבדיקה.
  • צריך לשנות את הגדרות המערכת לערך ברירת המחדל או לערך המקורי.
  • לא צריך להניח שמכשיר נמצא במצב מסוים, למשל מוכן ל-root. רוב הבדיקות לא דורשות הרשאת root כדי להריץ אותן. אם בדיקה מסוימת צריכה לדרוש הרשאת root, צריך לציין זאת באמצעות RootTargetPreparer ב-AndroidTest.xml שלה, כמו בדוגמה הבאה:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

יצירת קובצי מיפוי לבדיקה

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

דוגמה

זהו קובץ 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 הם השמות של כל קבוצת בדיקה. למידע נוסף על קבוצות בדיקה, ראו הגדרת קבוצות בדיקה.

אפשר להגדיר את השם של מודול הבדיקה או את השם של בדיקת השילוב של Trade Federation (נתיב המשאב לקובץ ה-XML לבדיקה, לדוגמה, uiautomator/uiautomator-demo) בערך של המאפיין name. שימו לב שלא ניתן להשתמש בשדה name בכיתה name או בשיטת הבדיקה name. כדי לצמצם את הבדיקות שרוצים להריץ, אפשר להשתמש באפשרויות כמו include-filter. דוגמה לשימוש ב-include-filter

ההגדרה host של בדיקה מציינת אם מדובר בבדיקת ללא מכשיר שפועלת במארח או לא. ערך ברירת המחדל הוא false, כלומר כדי להריץ את הבדיקה נדרש מכשיר. סוגי הבדיקות הנתמכים הם HostGTest לקובצי הבינארי של GTest ו-HostTest לבדיקות של JUnit.

המאפיין file_patterns מאפשר להגדיר רשימה של מחרוזות של ביטויים רגולריים להתאמה לנתיב היחסי של כל קובץ של קוד מקור (ביחס לתיקייה שמכילה את הקובץ TEST_MAPPING). בדוגמה, הבדיקה CtsWindowManagerDeviceTestCases פועלת לפני שליחת הקוד רק כשקובץ Java שמתחיל ב-Window או ב-Activity קיים באותה ספרייה שבה נמצא הקובץ TEST_MAPPING או באחת מספריות המשנה שלו. צריך להשתמש ב-escape עבור הקווים האחוריים (\) כי הם נמצאים בקובץ JSON.

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

המאפיין options מכיל אפשרויות נוספות של שורת הפקודה של Tradefed.

כדי לקבל רשימה מלאה של האפשרויות הזמינות לבדיקה מסוימת, מריצים את הפקודה:

tradefed.sh run commandAndExit [test_module] --help

למידע נוסף על אופן הפעולה של אופציות, אפשר לעיין במאמר טיפול באופציות ב-Tradefed.

הרצת בדיקות באמצעות Atest

כדי להריץ את כללי הבדיקה לפני שליחת הקוד באופן מקומי:

  1. עוברים לספרייה שמכילה את הקובץ TEST_MAPPING.
  2. מריצים את הפקודה:

    atest
    

כל הבדיקות לפני שליחת הקוד שמוגדרות בקובצי TEST_MAPPING בספרייה הנוכחית ובספריות ההורה שלה מופעלות. Atest מאתר ומריץ שני בדיקות (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 מפעילה רק בדיקות לפני שליחה שהוגדרו בקובץ TEST_MAPPING ב-CWD (או בתיקייה הנתונה) ובתיקיות ההורה שלו. אם רוצים להריץ בדיקות בכל הקבצים מסוג TEST_MAPPING בתיקיות המשנה, משתמשים באפשרות --include-subdir כדי לאלץ את Atest לכלול גם את הבדיקות האלה.

atest --include-subdir

בלי האפשרות --include-subdir, Atest מפעיל רק את הבדיקה A. כשמשתמשים באפשרות --include-subdir, המערכת מפעילה את Atest בשתי בדיקות (A ו-B).

תגובות ברמת השורה נתמכות

אפשר להוסיף הערה בפורמט // ברמת השורה כדי להרחיב את הקובץ TEST_MAPPING ולתאר את ההגדרה הבאה. ATest ו-Trade Federation מבצעים עיבוד מקדים של TEST_MAPPING לפורמט JSON תקין ללא הערות. כדי לשמור על ניקיון קובץ ה-JSON, יש תמיכה רק בהערות בפורמט // ברמת השורה.

דוגמה:

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