מדריך זה מנחה אותך דרך יצירת תצורת מבחן של "שלום עולם" (Tradefed או TF) ומעניק לך היכרות מעשית למסגרת TF. החל מסביבת פיתוח, תיצור תצורה פשוטה ותוסיף תכונות.
ההדרכה מציגה את תהליך פיתוח המבחן כסט של תרגילים, שכל אחד מהם מורכב ממספר שלבים, המדגימים כיצד לבנות ולחדד את התצורה שלך בהדרגה. כל הקוד לדוגמה שאתה צריך כדי להשלים את תצורת הבדיקה מסופק, והכותרת של כל תרגיל מסומנת באות המתארת את התפקידים המעורבים באותו שלב:
- D למפתחים
- אני עבור אינטגרטור
- R עבור רץ מבחן
לאחר השלמת המדריך, תהיה לך תצורת TF מתפקדת ותבין מושגים חשובים רבים במסגרת TF.
הגדר את פדרציית הסחר
לפרטים על הגדרת סביבת הפיתוח של TF, ראה הגדרת מכונה . שאר המדריך הזה מניח שיש לך מעטפת פתוחה שאותחלה לסביבת TF.
לשם הפשטות, מדריך זה ממחיש הוספת תצורה והמחלקות שלה לספריית הליבה של מסגרת TF. ניתן להרחיב את זה לפיתוח מודולים מחוץ לעץ המקור על ידי קומפילציה של ה-JAR המוזן במסחר, ולאחר מכן קומפילציה של המודולים שלך מול אותו JAR.
צור כיתת מבחן (D)
בואו ניצור מבחן שלום עולם שפשוט משליך הודעה ל-stdout. מבחן tradefed בדרך כלל מיישם את ממשק IRemoteTest . להלן יישום עבור HelloWorldTest:
package com.android.tradefed.example; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.invoker.TestInformation; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.result.ITestInvocationListener; import com.android.tradefed.testtype.IRemoteTest; public class HelloWorldTest implements IRemoteTest { @Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World!"); } }
שמור את הקוד לדוגמה הזה ב- <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
ובנה מחדש את tradefed מהמעטפת שלך:
m -jN
שים לב ש- CLog.i
בדוגמה שלמעלה משמש להפניית פלט לקונסולה. מידע נוסף על התחברות ב- Trade Federation מתואר ברישום (D, I, R) .
אם הבנייה לא מצליחה, עיין בהגדרת המכונה כדי לוודא שלא פספסת שלב.
צור תצורה (I)
בדיקות Trade Federation נעשות לניתנות להפעלה על ידי יצירת Configuration , קובץ XML המורה ל- tradefed על איזו בדיקה (או בדיקות) להפעיל, כמו גם אילו מודולים אחרים לבצע ובאיזה סדר.
בואו ניצור תצורה חדשה עבור HelloWorldTest שלנו (שים לב לשם המלא של הכיתה של HelloWorldTest):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
שמור נתונים אלה בקובץ helloworld.xml
בכל מקום במערכת הקבצים המקומית שלך (למשל /tmp/helloworld.xml
). TF ינתח את קובץ ה-XML של Configuration (aka config ), יטען את המחלקה שצוינה באמצעות רפלקציה, ייצור אותו, יעביר אותו ל- IRemoteTest
ויקרא לשיטת run
שלו.
הפעל את התצורה (R)
מהמעטפת שלך, הפעל את קונסולת tradefed:
tradefed.sh
ודא שהתקן מחובר למחשב המארח ושהוא גלוי ל- tradefed:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
ניתן לבצע תצורות באמצעות פקודת run <config>
console. לְנַסוֹת:
tf> run /tmp/helloworld.xml 05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
אתה אמור לראות "שלום, TF World!" פלט במסוף.
אתה יכול לאשר שפקודה מבוצעת על ידי שימוש list invocations
או li
בשורת המסוף, והיא לא אמורה להדפיס דבר. אם הפקודות פועלות כעת, הן מוצגות באופן הבא:
tf >l i Command Id Exec Time Device State 10 0m:00 [876X00GNG] running stub on build(s) 'BuildInfo{bid=0, target=stub, serial=876X00GNG}'
הוסף את התצורה לנתיב הכיתה (D, I, R)
לנוחות הפריסה, אתה יכול גם לאגד הגדרות לתוך ה-JARs המוזנים במסחר עצמם. Tradefed מזהה אוטומטית את כל התצורות המוצבות בתיקיות תצורה ב-classpath.
לשם המחשה, העבר את הקובץ helloworld.xml
לספריית הליבה tradefed ( <tree>/tools/tradefederation/core/res/config/example/helloworld.xml
). בנה מחדש את tradefed, הפעל מחדש את קונסולת tradefed, ואז בקש מ- tradefed להציג את רשימת התצורות מה-classpath:
tf> list configs […] example/helloworld: Runs the hello world test
כעת אתה יכול להפעיל את תצורת helloworld באמצעות:
tf> run example/helloworld 05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
אינטראקציה עם מכשיר (D, R)
עד כה, HelloWorldTest שלנו לא עושה שום דבר מעניין. המומחיות של Tradefed היא הפעלת בדיקות באמצעות מכשירי אנדרואיד, אז בואו נוסיף מכשיר אנדרואיד לבדיקה.
בדיקות יכולות לקבל הפניה למכשיר אנדרואיד על ידי שימוש TestInformation
, המסופק על ידי המסגרת כאשר קוראים לשיטת IRemoteTest#run
.
בואו נשנה את הודעת ההדפסה של HelloWorldTest כדי להציג את המספר הסידורי של המכשיר:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
כעת בנה מחדש את tradefed ובדוק את רשימת המכשירים:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
שימו לב למספר הסידורי הרשום כזמין ; זה המכשיר שצריך להקצות ל-HelloWorld:
tf> run example/helloworld 05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548
אתה אמור לראות את הודעת ההדפסה החדשה המציגה את המספר הסידורי של ההתקן.
שלח תוצאות בדיקה (D)
IRemoteTest
מדווח על תוצאות על ידי קריאה לשיטות במופע ITestInvocationListener שסופק לשיטת #run
. מסגרת TF עצמה אחראית לדיווח על ההתחלה (דרך ITestInvocationListener#invocationStarted ) והסיום (דרך ITestInvocationListener#invocationEnded ) של כל הזמנה.
ריצת בדיקה היא אוסף הגיוני של בדיקות. כדי לדווח על תוצאות בדיקה, IRemoteTest
אחראית לדווח על התחלת ריצת הבדיקה, ההתחלה והסיום של כל בדיקה וסיום ריצת הבדיקה.
כך עשוי להיראות יישום HelloWorldTest עם תוצאת בדיקה אחת שנכשלה.
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); TestDescription testId = new TestDescription("com.example.TestClassName", "sampleTest"); listener.testRunStarted("helloworldrun", 1); listener.testStarted(testId); listener.testFailed(testId, "oh noes, test failed"); listener.testEnded(testId, Collections.emptyMap()); listener.testRunEnded(0, Collections.emptyMap()); }
TF כולל מספר יישומי IRemoteTest
שתוכלו לעשות בהם שימוש חוזר במקום לכתוב משלכם מאפס. לדוגמה, InstrumentationTest יכול להריץ בדיקות של אפליקציית אנדרואיד מרחוק במכשיר אנדרואיד, לנתח את התוצאות ולהעביר תוצאות אלו ל- ITestInvocationListener
). לפרטים, ראה סוגי בדיקה .
אחסן את תוצאות הבדיקה (I)
יישום ברירת המחדל של מאזין הבדיקה עבור תצורת TF הוא TextResultReporter , אשר משליך את התוצאות של הזמנה ל-stdout. לשם המחשה, הפעל את תצורת HelloWorldTest מהסעיף הקודם:
./tradefed.sh
tf> run example/helloworld 04-29 18:25:55 I/TestInvocation: Invocation was started with cmd: /tmp/helloworld.xml 04-29 18:25:55 I/TestInvocation: Starting invocation for 'stub' with '[ BuildInfo{bid=0, target=stub, serial=876X00GNG} on device '876X00GNG'] 04-29 18:25:55 I/HelloWorldTest: Hello, TF World! I have device 876X00GNG 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Running helloworldrun: 1 tests 04-29 18:25:55 W/InvocationToJUnitResultForwarder: Test com.example.TestClassName#sampleTest failed with stack: oh noes, test failed 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Run ended in 0 ms
כדי לאחסן את התוצאות של הזמנה במקום אחר, כגון בקובץ, ציין מימוש ITestInvocationListener
מותאם אישית באמצעות תג result_reporter
בתצורה שלך.
TF כולל גם את המאזין XmlResultReporter , אשר כותב תוצאות בדיקה לקובץ XML בפורמט דומה לזה המשמש את כותב ה- Ant JUnit XML. כדי לציין את ה-Result_reporter בתצורה, ערוך את התצורה …/res/config/example/helloworld.xml
:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
כעת בנה מחדש את ה-Tradefed והרץ מחדש את מדגם Hello World:
tf> run example/helloworld 05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548 05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt 05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_2991649128735283633/host_log_6307746032218561704.txt 05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /tmp/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
שימו לב להודעת היומן המציינת כי נוצר קובץ XML; הקובץ שנוצר צריך להיראות כך:
<?xml version='1.0' encoding='UTF-8' ?> <testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"> <properties /> <testcase name="sampleTest" classname="com.example.TestClassName" time="0"> <failure>oh noes, test failed </failure> </testcase> </testsuite>
אתה יכול גם לכתוב מאזיני קריאות מותאמים אישית משלך - הם פשוט צריכים ליישם את ממשק ITestInvocationListener .
Tradefed תומך במספר מאזיני קריאות, כך שתוכל לשלוח תוצאות בדיקה למספר יעדים עצמאיים. כדי לעשות זאת, פשוט ציין מספר תגיות <result_reporter>
בתצורה שלך.
מתקני רישום (D, I, R)
מתקני הרישום של TF כוללים את היכולת:
- לכידת יומנים מהמכשיר (המכונה Device logcat)
- הקלט יומנים ממסגרת ה- Trade Federation הפועלת על המחשב המארח (המכונה יומן מארח)
מסגרת ה-TF לוכדת אוטומטית את ה-logcat מהמכשיר המוקצה ושולחת אותו למאזין הפניות לעיבוד. לאחר מכן, XmlResultReporter
שומר את logcat המכשיר שנלכד כקובץ.
יומני מארח TF מדווחים באמצעות המעטפת CLog עבור המחלקה ddmlib Log. בואו נמיר את הקריאה System.out.println
הקודמת ב-HelloWorldTest לקריאת CLog
:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
מטפל באינטרפולציה של מחרוזות ישירות, בדומה ל- String.format
. כאשר אתה בונה מחדש ומפעיל מחדש את TF, אתה אמור לראות את הודעת היומן ב-stdout:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
כברירת מחדל, tradefed מוציא הודעות יומן מארח ל-stdout . TF כולל גם מימוש יומן שכותב הודעות לקובץ: FileLogger . כדי להוסיף רישום קבצים, הוסף תג logger
לתצורה, תוך ציון שם המחלקה המלא של FileLogger
:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> <logger class="com.android.tradefed.log.FileLogger" /> </configuration>
כעת, בנה מחדש והפעל שוב את הדוגמה של helloworld:
tf >run example/helloworld … 05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt 05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt …
הודעת היומן מציינת את הנתיב של יומן המארח, שכאשר הוא מוצג, אמור להכיל את הודעת יומן ה-HelloWorldTest שלך:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
פלט לדוגמה:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
אפשרויות טיפול (D, I, R)
אובייקטים שנטענו מתצורת TF (המכונה גם Configuration objects ) יכולים לקבל נתונים מארגומנטים של שורת הפקודה באמצעות ההערה @Option
.
כדי להשתתף, מחלקת אובייקט Configuration מחילה את ההערה @Option
על שדה חבר ומספקת לו שם ייחודי. זה מאפשר לאכלס את ערך שדה החבר באמצעות אפשרות שורת פקודה (וגם מוסיף את האפשרות הזו באופן אוטומטי למערכת העזרה של התצורה).
הערה: לא כל סוגי השדות נתמכים. לתיאור של סוגים נתמכים, ראה OptionSetter .
בואו נוסיף @Option
ל-HelloWorldTest:
@Option(name="my_option", shortName='m', description="this is the option's help text", // always display this option in the default help text importance=Importance.ALWAYS) private String mMyOption = "thisisthedefault";
לאחר מכן, בוא נוסיף הודעת יומן כדי להציג את הערך של האפשרות ב-HelloWorldTest כדי שנוכל להוכיח שהיא התקבלה כהלכה:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
לבסוף, בנה מחדש את TF והפעל את helloworld; אתה אמור לראות הודעת יומן עם ערך ברירת המחדל my_option
:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
העבר ערכים משורת הפקודה
העבר ערך עבור my_option
; אתה אמור לראות my_option
מאוכלס בערך הזה:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
תצורות TF כוללות גם מערכת עזרה, המציגה אוטומטית טקסט עזרה עבור שדות @Option
. נסה את זה עכשיו, ואתה אמור לראות את טקסט העזרה עבור my_option
:
tf> run example/helloworld --help Printing help for only the important options. To see help for all options, use the --help-all flag cmd_options options: --[no-]help display the help text for the most important/critical options. Default: false. --[no-]help-all display the full help text for all options. Default: false. --[no-]loop keep running continuously. Default: false. test options: -m, --my_option this is the option's help text Default: thisisthedefault. 'file' logger options: --log-level-display the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
שימו לב להודעה על "הדפסת האפשרויות החשובות בלבד". כדי להפחית את עומס העזרה של אפשרויות, TF משתמש בתכונה Option#importance
כדי לקבוע אם להציג טקסט עזרה בשדה @Option
מסוים כאשר --help
מצוין. --help-all
תמיד מציג עזרה עבור כל שדות @Option
, ללא קשר לחשיבות. לפרטים, ראה Option.importance .
העבר ערכים מתצורה
אתה יכול גם לציין ערך Option בתוך התצורה על ידי הוספת אלמנט <option name="" value="">
. בדוק את זה באמצעות helloworld.xml
:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
בנייה מחדש והפעלת helloworld אמורה לייצר כעת את הפלט הזה:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
עזרת התצורה צריכה להתעדכן גם כדי לציין את ערך ברירת המחדל של my_option
:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
אובייקטי תצורה אחרים הכלולים בתצורת helloworld, כגון FileLogger
, מקבלים גם הם אפשרויות. האפשרות --log-level-display
מעניינת מכיוון שהיא מסננת את היומנים שמופיעים ב-stdout. מוקדם יותר במדריך, ייתכן ששמתם לב שהודעת היומן "שלום, TF World! יש לי מכשיר ..." הפסיקה להופיע ב-stdout לאחר שעברנו להשתמש FileLogger
. ניתן להגביר את רמת הרישום ל-stdout על ידי העברת --log-level-display
arg.
נסה זאת כעת, ואתה אמור לראות את הודעת היומן 'יש לי מכשיר' מופיעה שוב ב-stdout, בנוסף לכניסה לקובץ:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
זה הכל, אנשים!
כזכור, אם נתקעתם במשהו, לקוד המקור של Trade Federation יש הרבה מידע שימושי שלא נחשף בתיעוד. אם כל השאר נכשל, נסה לשאול בקבוצת Google של פלטפורמת אנדרואיד , עם "פדרציית סחר" בנושא ההודעה.