בדיקת המיפוי

זהו מבוא קצר של מיפוי בדיקות והסבר על האופן שבו ניתן לקבל התחילה להגדיר בדיקות בפרויקט הקוד הפתוח של Android (AOSP).

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

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

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

דוגמאות:

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

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

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

כללי סקריפט לבניית חבילה

כדי להשתתף במסגרת הבדיקה של Traade Federation כדי להריץ מודולים לבדיקה עבור build מסוים, המודולים test_suites מוגדר ל-Soong או LOCAL_COMPATIBILITY_SUITE ליצירת אחת משתי הסוויטות הבאות:

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

לדוגמה:

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

הגדרת בדיקות להפעלה בחבילת בדיקות

כדי להריץ בדיקה בתוך חבילת בדיקות:

  • לא ניתן לציין ספק build.
  • חייבות לנקות לאחר הסיום, לדוגמה, על ידי מחיקת קבצים שנוצרו במהלך הבדיקה.
  • יש לשנות את הגדרות המערכת לערך ברירת המחדל או הערך המקורי.
  • אין להניח שהמכשיר נמצא במצב מסוים, לדוגמה, מוכן לרמה הבסיסית (root). כדי להריץ את רוב הבדיקות לא נדרשת הרשאת בסיס. אם הבדיקה מחייבת שורש, הוא צריך לציין את זה עם 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": "CtsWindowManagerDeviceTestCases"
    }
  ],
  "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) לדוגמה).

ההגדרה 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 מכיל אפשרויות נוספות לשורת הפקודה מסוג Tradeified.

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

tradefed.sh run commandAndExit [test_module] --help

פרטים נוספים טיפול באפשרויות ב-Trended לפרטים נוספים על האפשרויות השונות.

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

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

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

    atest
    

כל הבדיקות שהוגשו מראש שהוגדרו ב-TEST_MAPPING הקבצים של ההגדרה הנוכחית והספרייה הראשית שלה מופעלות. Atest מאתר ומריץ שתי בדיקות להגשה מראש (A ו-B).

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

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

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

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

דוגמה:

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