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