این آموزش شما را از طریق ایجاد پیکربندی آزمایشی فدراسیون تجارت "سلام جهان" (Tradefed یا TF) راهنمایی می کند و به شما یک معرفی عملی با چارچوب TF می دهد. با شروع از یک محیط توسعه، یک پیکربندی ساده ایجاد کرده و ویژگی هایی را اضافه خواهید کرد.
این آموزش، فرآیند توسعه آزمون را به عنوان مجموعهای از تمرینها، که هر کدام از چندین مرحله تشکیل شده است، ارائه میکند که نشان میدهد چگونه پیکربندی خود را بسازید و به تدریج اصلاح کنید. تمام کد نمونه ای که برای تکمیل پیکربندی تست نیاز دارید ارائه شده است و عنوان هر تمرین با یک حرف توضیح داده شده است که نقش های دخیل در آن مرحله را توضیح می دهد:
- D برای توسعه دهنده
- من برای انتگرال
- R برای تست دونده
پس از تکمیل آموزش، پیکربندی TF کارآمدی خواهید داشت و بسیاری از مفاهیم مهم در چارچوب TF را درک خواهید کرد.
تشکیل فدراسیون تجارت
برای جزئیات در مورد تنظیم محیط توسعه TF، به تنظیمات ماشین مراجعه کنید. بقیه این آموزش فرض می کند که شما یک پوسته باز دارید که در محیط TF مقداردهی اولیه شده است.
برای سادگی، این آموزش اضافه کردن یک پیکربندی و کلاسهای آن به کتابخانه هسته چارچوب TF را نشان میدهد. این را می توان به توسعه ماژول ها در خارج از درخت منبع با کامپایل JAR تجارت شده و سپس کامپایل کردن ماژول های خود در برابر آن JAR گسترش داد.
ایجاد یک کلاس آزمایشی (D)
بیایید یک آزمایش hello world ایجاد کنیم که فقط یک پیام به 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
در مثال بالا برای هدایت خروجی به کنسول استفاده می شود. اطلاعات بیشتر در مورد ورود به سیستم در فدراسیون تجارت در Logging (D, I, R) توضیح داده شده است.
اگر ساخت موفق نشد، با Machine Setup مشورت کنید تا مطمئن شوید که یک مرحله را از دست نداده اید.
ایجاد یک پیکربندی (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 فایل Configuration XML (معروف به 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>
کنسول اجرا کرد. امتحان کنید:
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!
شما باید "Hello, 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)
برای سهولت در استقرار، میتوانید پیکربندیها را نیز در خود JARهای عرضهشده باندل کنید. Tradefed به طور خودکار تمام تنظیمات موجود در پوشه های پیکربندی در مسیر کلاس را تشخیص می دهد.
برای نشان دادن، فایل 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 اجرای آزمایشها با استفاده از دستگاههای Android است، بنابراین اجازه دهید یک دستگاه Android را به آزمایش اضافه کنیم.
تستها میتوانند با استفاده از TestInformation
، که توسط فریمورک ارائه میشود، هنگام فراخوانی متد IRemoteTest#run
ارجاع به دستگاه Android دریافت کنند.
بیایید پیام چاپی 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 ) هر Invocation است.
اجرای آزمایشی مجموعه ای منطقی از تست ها است. برای گزارش نتایج آزمون، 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 میتواند آزمایشهای یک برنامه Android را از راه دور بر روی یک دستگاه Android اجرا کند، نتایج را تجزیه کند و آن نتایج را به 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 شامل توانایی زیر است:
- ثبت گزارشها از دستگاه (معروف به دستگاه logcat)
- ثبت گزارشها از چارچوب فدراسیون تجارت در حال اجرا بر روی دستگاه میزبان (معروف به گزارش میزبان)
چارچوب 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 را بازسازی و دوباره اجرا می کنید، باید پیام log را در 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 …
پیام log مسیر گزارش میزبان را نشان می دهد، که در صورت مشاهده، باید حاوی پیام ورود به سیستم 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 (معروف به اشیاء پیکربندی ) همچنین می توانند داده ها را از آرگومان های خط فرمان از طریق استفاده از حاشیه نویسی @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 name="" value="">
یک مقدار Option را در پیکربندی مشخص کنید. آن را با استفاده از 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 نشان داده می شوند را فیلتر می کند. قبلاً در آموزش، ممکن است متوجه شده باشید که پیام گزارش "Hello, TF World! I have device…" پس از اینکه ما به استفاده از FileLogger
تغییر دادیم --log-level-display
در stdout نمایش داده نمی شود. --log-level-display
arg.
اکنون این را امتحان کنید، و باید مشاهده کنید که پیام گزارش "I have device" در stdout دوباره ظاهر می شود، علاوه بر اینکه به یک فایل وارد می شود:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
این همه، مردم!
به عنوان یادآوری، اگر در مورد چیزی گیر کرده اید، کد منبع فدراسیون تجارت اطلاعات مفید زیادی دارد که در اسناد نمایش داده نشده است. اگر همه چیز شکست خورد، سعی کنید از Google Group پلتفرم اندروید بپرسید، با عبارت Trade Federation در موضوع پیام.