הקטגוריה הזו של בדיקות מכשור לא שונה בהרבה מבדיקות שמיועדות לאפליקציות Android רגילות. חשוב לציין שאפליקציית הבדיקה שכוללת את המכשור צריכה להיות חתומה באותו אישור כמו האפליקציה שהיא מיועדת לה.
שימו לב: במדריך הזה אנחנו מניחים שיש לכם כבר ידע מסוים בתהליך העבודה של עץ המקור של הפלטפורמה. אם לא, כדאי לעיין במאמר דרישות. הדוגמה שמוסברת כאן היא כתיבת בדיקת מכשור חדשה עם חבילת יעד שהוגדרה בחבילת אפליקציית הבדיקה שלה. אם אתם לא מכירים את המושג, כדאי לקרוא את ההקדמה לבדיקות פלטפורמה.
במדריך הזה נשתמש במבחן הבא כדוגמה:
- frameworks/base/packages/Shell/tests
מומלץ לעיין בקוד כדי לקבל מושג כללי לפני שממשיכים.
קובעים את מיקום המקור
מכיוון שבדיקת המכשור תכוון לאפליקציה, המוסכמה היא למקם את קוד המקור של הבדיקה בספרייה tests
מתחת לשורש של ספריית מקור הרכיב בעץ המקור של הפלטפורמה.
אפשר לקרוא דיונים נוספים על מיקום המקור בדוגמה מקצה לקצה לבדיקות עם הטמעה עצמית.
קובץ מניפסט
בדומה לאפליקציה רגילה, לכל מודול של בדיקת מכשור נדרש קובץ מניפסט. אם תתנו לקובץ את השם AndroidManifest.xml
ותספקו אותו לצד Android.mk
עבור מודול הבדיקה, הוא ייכלל אוטומטית על ידי קובץ ה-Makefile הראשי BUILD_PACKAGE
.
לפני שממשיכים, מומלץ מאוד לעיין בסקירה הכללית של מניפסט האפליקציה.
במאמר הזה מוצגת סקירה כללית של הרכיבים הבסיסיים של קובץ מניפסט והפונקציונליות שלהם.
אפשר לגשת לגרסה האחרונה של קובץ המניפסט לשינוי לדוגמה ב-Gerrit בכתובת: https://android.googlesource.com/platform/frameworks/base/+/android16-release/packages/Shell/tests/AndroidManifest.xml
לנוחותכם, הנה תמונת מצב:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
<application>
<uses-library android:name="android.test.runner" />
<activity
android:name="com.android.shell.ActionSendMultipleConsumerActivity"
android:label="ActionSendMultipleConsumer"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
</manifest>
כמה הערות על קובץ המניפסט:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
מאפיין package
הוא שם חבילת האפליקציה: זהו המזהה הייחודי שמשמש את מסגרת האפליקציה של Android לזיהוי אפליקציה (או בהקשר הזה: אפליקציית הבדיקה שלכם). כל משתמש במערכת יכול להתקין רק אפליקציה אחת עם שם החבילה הזה.
מכיוון שמדובר בחבילת אפליקציה לבדיקה, שאינה תלויה בחבילת האפליקציה שנבדקת, צריך להשתמש בשם חבילה שונה. אחת מהמוסכמות הנפוצות היא להוסיף את הסיומת .test
.
בנוסף, המאפיין package
זהה למה שמוחזר מ-ComponentName#getPackageName()
, וגם למה שמשמש לאינטראקציה עם פקודות משנה שונות של pm
דרך adb shell
.
חשוב גם לציין שלמרות ששם החבילה הוא בדרך כלל באותו סגנון כמו שם חבילה ב-Java, בפועל אין לו קשר רב אליו. במילים אחרות, חבילת האפליקציה (או הבדיקה) יכולה להכיל מחלקות עם שמות חבילות כלשהם, אבל מצד שני, אפשר לבחור בפשטות ולתת לחבילת ה-Java ברמה העליונה באפליקציה או בבדיקה שם זהה לשם חבילת האפליקציה.
<uses-library android:name="android.test.runner" />
הדבר נדרש לכל בדיקות המכשור, כי המחלקות הקשורות ארוזות בקובץ jar של ספריית framework נפרדת, ולכן נדרשים ערכים נוספים של נתיב מחלקות כשחבילת הבדיקה מופעלת על ידי framework של האפליקציה.
android:targetPackage="com.android.shell"
ההגדרה הזו קובעת את חבילת היעד של המדידה ל-com.android.shell
.
כשמפעילים את המכשור באמצעות הפקודה am instrument
, המסגרת מפעילה מחדש את התהליך com.android.shell
ומזריקה קוד מכשור לתהליך לצורך ביצוע הבדיקה. המשמעות היא גם שלקוד הבדיקה תהיה גישה לכל המופעים של המחלקה שפועלים באפליקציה שנבדקת, והוא יוכל לשנות את המצב בהתאם לנקודות החיבור לבדיקה שנחשפות.
קובץ תצורה פשוט
לכל מודול בדיקה חדש צריך להיות קובץ הגדרה שמנחה את מערכת ה-build באמצעות מטא-נתונים של המודול, יחסי תלות בזמן הקומפילציה והוראות אריזה. ברוב המקרים, האפשרות של קובץ Blueprint מבוסס Soong מספיקה. פרטים נוספים זמינים במאמר בנושא הגדרת בדיקה פשוטה.
קובץ תצורה מורכב
בבדיקות מורכבות יותר, צריך גם לכתוב קובץ הגדרות בדיקה עבור מסגרת הבדיקה של Android, Trade Federation.
בהגדרת הבדיקה אפשר לציין אפשרויות מיוחדות להגדרת המכשיר וארגומנטים שמוגדרים כברירת מחדל כדי לספק את מחלקת הבדיקה.
אפשר לגשת לגרסה העדכנית של קובץ התצורה של שינוי gerrit לדוגמה בכתובת: frameworks/base/packages/Shell/tests/AndroidTest.xml
לנוחותכם, הנה תמונת מצב:
<configuration description="Runs Tests for Shell.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="ShellTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.shell.tests" />
<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="ShellTests.apk"/>
</target_preparer>
הפקודה הזו אומרת ל-Trade Federation להתקין את ShellTests.apk במכשיר היעד באמצעות target_preparer שצוין. יש הרבה כלי הכנה ליעדים שזמינים למפתחים ב-Trade Federation, ואפשר להשתמש בהם כדי לוודא שהמכשיר מוגדר בצורה נכונה לפני הפעלת הבדיקה.
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.shell.tests"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
הפרמטר הזה מציין את מחלקת הבדיקה של Trade Federation שבה יש להשתמש כדי להריץ את הבדיקה, ומעביר את החבילה במכשיר להרצה ואת מסגרת ההרצה של הבדיקה, שהיא JUnit במקרה הזה.
מידע נוסף על בדיקת הגדרות של מודולים
תכונות של JUnit4
השימוש בספריית android-support-test
ככלי להרצת בדיקות מאפשר אימוץ של מחלקות בדיקה חדשות בסגנון JUnit4, ושינוי לדוגמה ב-Gerrit מכיל שימוש בסיסי מאוד בתכונות שלה.
קוד המקור העדכני של שינוי לדוגמה ב-Gerrit זמין בכתובת: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
דפוסי בדיקה הם בדרך כלל ספציפיים לצוותי רכיבים, אבל יש כמה דפוסי שימוש שימושיים באופן כללי.
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {
הבדל משמעותי ב-JUnit4 הוא שלא נדרש יותר שהבדיקות יירשו ממחלקת בדיקה בסיסית משותפת. במקום זאת, כותבים בדיקות במחלקות Java רגילות ומשתמשים בהערה כדי לציין הגדרות ומגבלות מסוימות של הבדיקה. בדוגמה הזו, אנחנו מציינים שהמחלקה הזו צריכה לפעול כבדיקת JUnit4 של Android.
ההערה @SmallTest
מציינת גודל בדיקה לכל מחלקת הבדיקה: כל שיטות הבדיקה שנוספו למחלקת הבדיקה הזו מקבלות בירושה את הערת גודל הבדיקה הזו.
הגדרה לפני מחלקת הבדיקה, ניקוי אחרי הבדיקה וניקוי אחרי מחלקת הבדיקה:
בדומה לשיטות setUp
ו-tearDown
ב-JUnit4.
ההערה Test
משמשת להוספת הערות לבדיקה בפועל.
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
ההערה @Before
משמשת בשיטות של JUnit4 כדי לבצע הגדרה לפני הבדיקה.
למרות שלא נעשה בו שימוש בדוגמה הזו, יש גם @After
לביטול ההגדרה אחרי הבדיקה.
באופן דומה, אפשר להשתמש בהערות @BeforeClass
ו-@AfterClass
במתודות של JUnit4 כדי לבצע הגדרה לפני הפעלת כל הבדיקות בכיתת בדיקה, ופירוק לאחר מכן. הערה: שיטות ההגדרה והביטול של היקף המחלקה חייבות להיות סטטיות.
בנוגע לשיטות הבדיקה, בניגוד לגרסה קודמת של JUnit, כבר לא צריך להתחיל את שם השיטה ב-test
, אלא כל אחת מהן צריכה להיות מסומנת ב-@Test
. כמו תמיד, שיטות בדיקה צריכות להיות ציבוריות, לא להצהיר על ערך החזרה, לא לקבל פרמטרים ולהיות מסוגלות להחזיר חריגים.
Context context = InstrumentationRegistry.getTargetContext();
מכיוון שבדיקות JUnit4 לא דורשות יותר מחלקת בסיס משותפת, אין יותר צורך להשיג מופעים של Context
באמצעות getContext()
או של getTargetContext()
באמצעות שיטות של מחלקת בסיס. במקום זאת, רכיב ההרצה החדש של הבדיקות מנהל אותם באמצעות InstrumentationRegistry
, שבו מאוחסן ההגדרה ההקשרית והסביבתית שנוצרה על ידי מסגרת המכשור. במסגרת השיעור הזה, אפשר גם להתקשר אל:
-
getInstrumentation()
: המופע למחלקהInstrumentation
-
getArguments()
: הארגומנטים בשורת הפקודה שמועברים אלam instrument
דרך-e <key> <value>
פיתוח ובדיקה באופן מקומי
בתרחישים הנפוצים ביותר, כדאי להשתמש ב-Atest.
במקרים מורכבים יותר שדורשים התאמה אישית נרחבת, צריך לפעול לפי ההוראות להטמעה.