כשמפעילים בדיקת מכשור, חבילת היעד מופעלת מחדש עם הזרקה של קוד מכשור והפעלה שלו. חריג אחד הוא שחבילה היעד כאן לא יכולה להיות מסגרת האפליקציה של Android עצמה, כמו החבילה android
, כי הפעולה הזו תוביל למצב פרדוקסלי שבו תצטרכו להפעיל מחדש את מסגרת Android, שמספקת תמיכה בפונקציות המערכת, כולל בכלי המדידה עצמו.
כלומר, בדיקת כלי למדידת ביצועים לא יכולה להחדיר את עצמה למסגרת Android, שנקראת גם שרת המערכת, לצורך ביצוע. כדי לבדוק את ה-framework של Android, קוד הבדיקה יכול להפעיל רק פלטפורמות API ציבוריות, או פלטפורמות שנחשפו באמצעות Android Interface Definition Language (AIDL) שזמינות בעץ המקור של הפלטפורמה. בקטגוריה הזו של בדיקות, אין משמעות לטרגוט של חבילה מסוימת. לכן, מקובל להצהיר על מכשירי המדידה האלה כמיועדים לטירגוט של חבילת אפליקציית הבדיקה שלהם, כפי שהוגדר בתג <manifest>
של AndroidManifest.xml
.
בהתאם לדרישות, חבילות של אפליקציות לבדיקה בקטגוריה הזו יכולות גם:
- מקבץ פעילויות שנדרשות לבדיקה.
- משתפים את מזהה המשתמש עם המערכת.
- להיות חתומות במפתח הפלטפורמה.
- להיות יעברו הידור לפי המקור של ה-framework ולא לפי ה-SDK הציבורי.
הקטגוריה הזו של בדיקות אינסטרומנטציה נקראת לפעמים אינסטרומנטציה עצמית. ריכזנו כאן כמה דוגמאות לבדיקות של הטמעת מכשירי מדידה עצמית במקור הפלטפורמה:
בדוגמה הזו מוסבר איך לכתוב בדיקת אינסטרומנטציה חדשה, עם חבילת יעד שמוגדרת בחבילה של אפליקציית בדיקה משלה. במדריך הזה נעשה שימוש בבדיקות הבאות לדוגמה:
מומלץ לעיין בקוד קודם כדי לקבל תמונה כללית לפני שממשיכים.
בחירת מיקום מקור
בדרך כלל לצוות כבר יש דפוס קבוע של מקומות לבדיקה בקוד ומקומות להוספת בדיקות. לרוב הצוותים יש מאגר git יחיד, או שהם משתפים מאגר עם צוותים אחרים, אבל יש להם ספריית משנה ייעודית שמכילה את קוד המקור של הרכיבים.
בהנחה שמיקום השורש של מקור הרכיבים הוא <component source
root>
, לרוב הרכיבים יש תיקיות src
ו-tests
מתחתיו, וגם כמה קבצים נוספים כמו Android.mk
(או קבצים .mk
נוספים), קובץ המניפסט AndroidManifest.xml
וקובץ הגדרת הבדיקה AndroidTest.xml.
מכיוון שאתם מוסיפים בדיקה חדשה לגמרי, סביר להניח שתצטרכו ליצור את הספרייה tests
לצד הרכיב src
וליישב אותה בתוכן.
במקרים מסוימים, יכול להיות לצוות שלכם יש מבני ספריות נוספים ב-tests
בגלל הצורך לארוז חבילות שונות של בדיקות ל-APKs נפרדים. במקרה כזה, צריך ליצור ספריית משנה חדשה בשם tests
.
ללא קשר למבנה, בסוף תצטרכו לאכלס את הספרייה tests
או את ספריית המשנה החדשה שנוצרה בקבצים שדומים לאלה שבספרייה instrumentation
בשינוי לדוגמה ב-Gerrit. הפרטים של כל קובץ מוסברים בהמשך המסמך.
קובץ מניפסט
בדומה לפרויקט אפליקציה, לכל מודול של בדיקת מכשור נדרש קובץ מניפסט שנקרא AndroidManifest.xml
. כדי לכלול את הקובץ הזה באופן אוטומטי באמצעות קובץ ה-makefile של הליבה BUILD_PACKAGE
, צריך לספק את הקובץ הזה לצד הקובץ Android.mk
של מודול הבדיקה.
אם אתם לא מכירים את הקובץ AndroidManifest.xml
, תוכלו לעיין במאמר סקירה כללית של מניפסט האפליקציות
לפניכם קובץ AndroidManifest.xml
לדוגמה:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.system"
package="android.test.example.helloworld" >
<application>
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.test.example.helloworld"
android:label="Hello World Test"/>
</manifest>
הערות נבחרות לגבי קובץ המניפסט:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
המאפיין package
הוא שם החבילה של האפליקציה: זהו המזהה הייחודי שמשמש את מסגרת האפליקציות של Android לזיהוי אפליקציה (או בהקשר הזה: אפליקציית הבדיקה). כל משתמש במערכת יכול להתקין רק אפליקציה אחת עם שם החבילה הזה.
בנוסף, המאפיין package
זהה למה שמוחזר על ידי ComponentName#getPackageName()
, וגם זה שמשתמשים בו כדי לקיים אינטראקציה עם פקודות משנה שונות של pm
באמצעות adb shell
.
שימו לב שלמרות ששם החבילה הוא בדרך כלל באותו סגנון כמו שם החבילה של Java, יש למעשה מעט מאוד דברים לעשות איתו. במילים אחרות, חבילה של אפליקציה (או בדיקה) עשויה להכיל כיתות עם כל שמות החבילות, אבל מצד שני, אפשר לבחור בפשטות ולתת לחבילת Java ברמה העליונה באפליקציה או בבדיקה שם זהה לשם חבילת האפליקציה.
android:sharedUserId="android.uid.system"
ההצהרה הזו קובעת שבזמן ההתקנה, לקובץ ה-APK הזה צריך להקצות את אותו מזהה משתמש, כלומר זהות בסביבת זמן הריצה, כמו לפלטפורמת הליבה. חשוב לזכור שהדבר תלוי בכך שקובץ ה-APK חתום באותו אישור שבו חתומה הפלטפורמה המרכזית (ראו LOCAL_CERTIFICATE
בקטע הקודם), אבל מדובר במושגים שונים:
- חלק מההרשאות או מממשקי ה-API מוגנים בחתימה, מה שמחייב את אותו אישור חתימה
- חלק מההרשאות או ממשקי ה-API דורשים את זהות המשתמש
system
של מבצע הקריאה החוזרת, ולכן חבילת הקריאה החוזרת צריכה לשתף את מזהה המשתמש עםsystem
, אם היא חבילת API נפרדת מהפלטפורמה עצמה
<uses-library android:name="android.test.runner" />
הדבר נדרש לכל בדיקות ה-Instrumentation, כי הכיתות הקשורות ארוזות בקובץ ספרייה נפרד של framework JAR, ולכן נדרשות רשומות נוספות ב-classpath כשחבילת הבדיקה מופעלת על ידי מסגרת האפליקציה.
android:targetPackage="android.test.example.helloworld"
יכול להיות ששמתם לב שהמאפיין targetPackage
שמוצהר כאן זהה למאפיין package
שמוצהר בתג manifest
בקובץ הזה. כפי שצוין בקטע יסודות הבדיקה, קטגוריית הבדיקות הזו מיועדת בדרך כלל לבדיקת ממשקי API של מסגרות, ולכן אין הרבה משמעות לכך שתהיה להן חבילת אפליקציה ספציפית שמוגדרת כמטרה, מלבד עצמה.
קובץ תצורה פשוט
לכל מודול בדיקה חדש צריך להיות קובץ תצורה כדי להנחות את מערכת ה-build עם המטא-נתונים של המודול, יחסי התלות בזמן הידור והוראות האריזה. ברוב המקרים, האפשרות של קובץ Blueprint שמבוססת על סונג תספיק. לפרטים נוספים, ראו הגדרת בדיקה פשוטה.
קובץ תצורה מורכב
במקרים מורכבים יותר, צריך גם לכתוב קובץ תצורה של בדיקה ל-Trade Federation, ערכת הבדיקה של Android.
בהגדרות האישיות של הבדיקה אפשר לציין אפשרויות הגדרה מיוחדות של המכשיר וארגומנטים (ארגומנטים) שמוגדרים כברירת מחדל כדי לספק את מחלקה לבדיקה. ראו את הדוגמה בכתובת /platform_testing/tests/example/instrumentation/AndroidTest.xml.
צירפנו כאן תמונת מצב לצורך נוחות:
<configuration description="Runs sample instrumentation test.">
<target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
<option name="test-suite-tag" value="apct"/>
<option name="test-tag" value="SampleInstrumentationTest"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.test.example.helloworld"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>
הערות נבחרות לגבי קובץ התצורה של הבדיקה:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
הפקודה הזו מורה ל-Trade Federation להתקין את HelloWorldTests.apk במכשיר היעד באמצעות target_preparer שצוין. למפתחים יש גישה לכלי רבים להכנת מטרות ב-Trade Federation, שאפשר להשתמש בהם כדי לוודא שהמכשיר מוגדר כראוי לפני ביצוע הבדיקה.
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.test.example.helloworld"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
כאן מציינים את סוג הבדיקה של Trade Federation שרוצים להשתמש בו כדי להריץ את הבדיקה, ומעבירים את החבילה במכשיר שרוצים להריץ אותה ואת מסגרת ה-test runner, שהיא JUnit במקרה הזה.
למידע נוסף, ראו הגדרות של מודול בדיקה.
תכונות של JUnit4
שימוש בספרייה android-support-test
ככלי להרצת בדיקות מאפשר להשתמש בסוגים חדשים של כיתות בדיקה בסגנון JUnit4, והשינוי לדוגמה ב-Gerrit מכיל שימוש בסיסי מאוד בתכונות שלה. אפשר לראות את הדוגמה בכתובת /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java.
דפוסי הבדיקה בדרך כלל ספציפיים לצוותים של הרכיבים, אבל יש כמה דפוסי שימוש שימושיים באופן כללי.
@RunWith(JUnit4.class)
public class HelloWorldTest {
הבדל משמעותי ב-JUnit4 הוא שבבדיקות כבר אין צורך בירושה ממערך בדיקות בסיסי משותף. במקום זאת, כותבים בדיקות בכיתות Java רגילות ומשתמשים בהערות כדי לציין הגדרות ומגבלות מסוימות של בדיקות. בדוגמה הזו, אנחנו מורים להריץ את המחלקה הזו כבדיקה של JUnit4.
@BeforeClass
public static void beforeClass() {
...
@AfterClass
public static void afterClass() {
...
@Before
public void before() {
...
@After
public void after() {
...
@Test
@SmallTest
public void testHelloWorld() {
...
בהערות @Before
ו-@After
נעשה שימוש ב-methods של JUnit4 כדי לבצע הגדרה לפני הבדיקה ואחרי הבדיקה. באופן דומה, אנו משתמשים באנוטציות @BeforeClass
ו-@AfterClass
בשיטות של JUnit4 לביצוע הגדרה לפני ביצוע כל הבדיקות בשיעור בדיקה, ואחר כך לפרק אותן. חשוב לזכור ששיטות ההגדרה והפירוק ברמת הכיתה חייבות להיות סטטיות. בנוגע לשיטות הבדיקה, שלא כמו בגרסה הקודמת של JUnit, כבר לא צריך להתחיל את שם ה-method ב-test
, ובמקום זאת צריך להוסיף לכל אחת הערות הערות עם @Test
. כרגיל, שיטות הבדיקה צריכות להיות ציבוריות, לא להצהיר על ערך החזרה, לא לקבל פרמטרים ויכולות להוציא חריגות.
גישה לכיתה של מכשירי המדידה
הדוגמה הבסיסית של hello world לא כוללת את הנושא הזה, אבל לעתים קרובות נדרש מופע Instrumentation
לגישה במהלך בדיקת Android. זהו ממשק ה-API המרכזי שמספק גישה להקשרים של אפליקציות, לממשקי API לבדיקה שקשורים למחזור החיים של הפעילות ועוד.
מאחר שבבדיקות JUnit4 כבר אין צורך בכיתה בסיסית משותפת, אין יותר צורך לקבל מופע של Instrumentation
דרך InstrumentationTestCase#getInstrumentation()
. במקום זאת, מנהל הבדיקות החדש מנהל אותו דרך InstrumentationRegistry
, שבו מאוחסן ההגדרה ההקשרית והסביבתית שנוצרה על ידי מסגרת המדידה.
כדי לגשת למופעים של המחלקה Instrumentation
, פשוט קוראים לשיטה הסטטית getInstrumentation()
במחלקה InstrumentationRegistry
:
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
פיתוח ובדיקה באופן מקומי
בתרחישים הנפוצים ביותר לדוגמה, כדאי להשתמש ב-Atest.
במקרים מורכבים יותר שדורשים התאמה אישית משמעותית יותר, פועלים לפי הוראות המדידה.