דוגמא למבחני מכשור עצמי

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

משמעות הדבר היא שבדיקת מכשור אינה יכולה להחדיר את עצמה למסגרת אנדרואיד, הלא היא שרת המערכת, לצורך ביצוע. על מנת לבדוק את מסגרת האנדרואיד, קוד הבדיקה יכול להפעיל רק משטחי API ציבוריים, או כאלה שנחשפו באמצעות שפת הגדרת ממשק אנדרואיד AIDL הזמינה בעץ המקור של הפלטפורמה. עבור קטגוריית בדיקות זו, אין משמעות למקד לאף חבילה מסוימת. לכן, נהוג שמכשור כזה יוכרז כמיקוד לחבילת יישומי בדיקה משלו, כפי שמוגדר בתג <manifest> משלו של AndroidManifest.xml .

בהתאם לדרישות, חבילות יישום לבדיקה בקטגוריה זו עשויות גם:

  • חבילת פעילויות הדרושות לבדיקה.
  • שתף את זיהוי המשתמש עם המערכת.
  • תהיה חתום עם מפתח הפלטפורמה.
  • הידור לפי מקור המסגרת ולא ה-SDK הציבורי.

קטגוריה זו של מבחני מכשור מכונה לפעמים מכשור עצמי. הנה כמה דוגמאות למבחני מכשור עצמי במקור הפלטפורמה:

הדוגמה המכוסה כאן היא כתיבת מבחן מכשור חדש עם חבילת יעד מוגדרת בחבילת יישום בדיקה משלה. מדריך זה משתמש במבחן הבא כדי לשמש דוגמה:

מומלץ לעיין קודם בקוד כדי לקבל רושם גס לפני שתמשיך.

החליטו על מיקום המקור

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

בהנחה שמיקום השורש עבור מקור הרכיב שלך נמצא ב- <component source root> , לרוב הרכיבים יש תיקיות src tests תחתיו, וכמה קבצים נוספים כגון Android.mk (או מחולקים לקובצי .mk נוספים), קובץ המניפסט AndroidManifest.xml , וקובץ תצורת הבדיקה 'AndroidTest.xml'.

מכיוון שאתה מוסיף בדיקה חדשה לגמרי, כנראה שתצטרך ליצור את ספריית tests שליד הרכיב src שלך, ולאכלס אותה בתוכן.

במקרים מסוימים, ייתכן שלצוות שלך יהיו מבני ספרייה נוספים tests עקב הצורך לארוז חבילות בדיקות שונות ל-APKs בודדים. ובמקרה זה, תצטרך ליצור ספריית משנה חדשה תחת tests .

ללא קשר למבנה, בסופו של דבר תאכלס את ספריית tests או את ספריית המשנה החדשה שנוצרה בקבצים דומים למה שנמצא בספריית instrumentation ב-gerrit change לדוגמה. הפרטים של כל תיק מוסברים בהמשך מסמך זה.

קובץ מניפסט

כמו בפרויקט אפליקציה, כל מודול בדיקת מכשור דורש קובץ מניפסט בשם AndroidManifest.xml . כדי לכלול קובץ זה באופן אוטומטי באמצעות קובץ הליבה BUILD_PACKAGE makefile, ספק את הקובץ הזה לצד קובץ 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 , אם זו חבילה נפרדת מפלטפורמת הליבה עצמה
<uses-library android:name="android.test.runner" />

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

android:targetPackage="android.test.example.helloworld"

אולי שמתם לב שה- targetPackage כאן מוכרז זהה לתכונת package המוצהרת בתג manifest של הקובץ הזה. כפי שהוזכר ביסודות הבדיקה , קטגוריה זו של בדיקות מכשור נועדה בדרך כלל לבדיקת ממשקי API של מסגרת, כך שזה לא מאוד משמעותי שתהיה להם חבילת יישומים ממוקדת ספציפית, מלבד עצמה.

קובץ תצורה פשוט

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

קובץ תצורה מורכב

עבור מקרים מורכבים יותר אלה, עליך לכתוב גם קובץ תצורת בדיקה עבור רתמת הבדיקה של אנדרואיד, Trade Federation .

תצורת הבדיקה יכולה לציין אפשרויות מיוחדות להגדרת התקן וארגומנטים של ברירת מחדל כדי לספק את מחלקת הבדיקה. ראה את הדוגמה בכתובת /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 שצוין. ישנם מכיני יעדים רבים זמינים למפתחים ב-Trader 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 לשימוש לביצוע הבדיקה ועובר בחבילה במכשיר שיש לבצע ובמסגרת הרץ של הבדיקה שהיא JUnit במקרה זה.

למידע נוסף, ראה בדיקת הגדרות מודול .

תכונות JUnit4

שימוש בספריית android-support-test כרץ מבחן מאפשר אימוץ של מחלקות בדיקה חדשות בסגנון JUnit4, והשינוי הגריט לדוגמה מכיל שימוש בסיסי מאוד בתכונות שלו. ראה את הדוגמה בכתובת /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 משמשות בשיטות של JUnit4 לביצוע התקנת טרום בדיקה והפסקה לאחר הבדיקה. באופן דומה, ההערות @BeforeClass ו- @AfterClass משמשות בשיטות של JUnit4 לביצוע הגדרה לפני ביצוע כל הבדיקות במחלקת בדיקה, והפסקה לאחר מכן. שים לב ששיטות ההגדרה והפירוק של היקף הכיתה חייבות להיות סטטיות. באשר לשיטות הבדיקה, שלא כמו בגרסה הקודמת של JUnit, הן כבר לא צריכות להתחיל את שם השיטה ב- test , במקום זאת, יש להוסיף הערות לכל אחת מהן ב- @Test . כרגיל, שיטות הבדיקה חייבות להיות ציבוריות, להצהיר ללא ערך החזרה, ללא פרמטרים, ועשויות לזרוק חריגים.

גישה למחלקת מכשור

למרות שלא מכוסה בדוגמה הבסיסית של שלום עולם, זה די נפוץ שמבחן אנדרואיד דורש גישה למופע Instrumentation : זהו ממשק ה-API הליבה המספק גישה להקשרים של יישומים, ממשקי API לבדיקה הקשורים למחזור החיים ועוד.

מכיוון שמבחני JUnit4 כבר לא דורשים מחלקה בסיס משותפת, אין עוד צורך להשיג מופע Instrumentation דרך InstrumentationTestCase#getInstrumentation() , במקום זאת, רץ המבחן החדש מנהל אותו באמצעות InstrumentationRegistry שבו מאוחסנים הגדרות הקשריות וסביבתיות שנוצרו על ידי מסגרת מכשור.

כדי לגשת למופע של מחלקת Instrumentation , פשוט קרא למתודה הסטטית getInstrumentation() במחלקה InstrumentationRegistry :

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

בנה ובדוק באופן מקומי

למקרי השימוש הנפוצים ביותר, השתמש ב-Atest .

למקרים מורכבים יותר הדורשים התאמה אישית כבדה יותר, עקוב אחר הוראות המכשור .