דוגמה לטירגוט אפליקציה

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

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

במדריך הזה נעשה שימוש בבדיקה הבאה כדוגמה:

  • frameworks/base/packages/Shell/tests

מומלץ לעיין בקוד קודם כדי לקבל תמונה כללית לפני שממשיכים.

בחירת מיקום מקור

מכיוון שבדיקה של מכשור תתמקד באפליקציה, מומלץ למקם את קוד המקור של הבדיקה בתיקייה tests ברמה הבסיסית של תיקיית המקור של הרכיב בעץ המקור של הפלטפורמה.

מידע נוסף על מיקום המקור זמין בדוגמה מקצה לקצה לבדיקות עם הטמעה עצמית של כלי למדידת ביצועים.

קובץ מניפסט

כמו באפליקציה רגילה, לכל מודול בדיקה של מכשירי מדידה נדרש קובץ מניפסט. אם נותנים לקובץ את השם AndroidManifest.xml ומציינים אותו לצד Android.mk עבור מודול הבדיקה, הוא ייכלל באופן אוטומטי בקובץ ה-makefile של הליבה BUILD_PACKAGE.

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

כאן מוצגת סקירה כללית של הרכיבים הבסיסיים של קובץ מניפסט והפונקציונליות שלהם.

הגרסה האחרונה של קובץ המניפסט לשינוי לדוגמה ב-Gerrit זמינה בכתובת: https://android.googlesource.com/platform/frameworks/base/+/main/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" />

הדבר נדרש לכל בדיקות ה-Instrumentation, כי הכיתות הקשורות ארוזות בקובץ ספרייה נפרד של framework jar, ולכן נדרשות רשומות נוספות ב-classpath כשחבילת הבדיקה מופעלת על ידי מסגרת האפליקציה.

android:targetPackage="com.android.shell"

הפקודה הזו מגדירה את חבילת היעד של הכלי למדידת ביצועים כ-com.android.shell. כשמפעילים את האינסטרומנטציה באמצעות הפקודה am instrument, המסגרת מפעילה מחדש את התהליך com.android.shell ומחדירה לתוכו את קוד האינסטרומנטציה לצורך ביצוע הבדיקה. המשמעות היא גם שלקוד הבדיקה תהיה גישה לכל המופעים של הכיתה שפועלים באפליקציה שנבדקת, ויכול להיות שהוא יוכל לשנות את המצב בהתאם ל-test hooks שנחשפו.

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

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

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

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

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

הגרסה העדכנית ביותר של קובץ התצורה של השינוי לדוגמה ב-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 שמשמש להרצת הבדיקה, והוא מעביר את החבילה במכשיר להרצה ואת מסגרת ה-test runner, שהיא 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 רגילות ומשתמשים בהערות כדי לציין הגדרות ומגבלות מסוימות של בדיקות. בדוגמה הזו, אנחנו מורים להריץ את המחלקה הזו כבדיקה של Android JUnit4.

ההערה @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.

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