يرشدك هذا الدليل التوجيهي خلال عملية إنشاء "hello world" اتحاد تجاري إعداد الاختبار (الفريق التقليدي أو TF) ويمنحك مقدمة عملية عن فريق العمل (TF) إطار العمل. بدءًا من بيئة تطوير، ستقوم بإنشاء تصميم على تهيئة الميزات وإضافتها.
يقدم البرنامج التعليمي عملية تطوير الاختبار كمجموعة من التمارين، يتكون كل منها من عدة خطوات، توضح كيفية إنشاء كل منها تحسين التهيئة. كل رمز نموذجي تحتاجه لإكمال الاختبار التصميم، وتتم إضافة تعليق توضيحي إلى عنوان كل تمرين حرف يصف الأدوار المتضمنة في هذه الخطوة:
- D للمطوّرين
- I لشركة التكامل
- R لأداة تشغيل الاختبار
بعد إكمال الدليل التوجيهي، ستكون لديك إعدادات TF صالحة وفهم العديد من المفاهيم المهمة في إطار عمل TF.
إعداد اتحاد تجاري
للحصول على تفاصيل حول إعداد بيئة تطوير TF، يمكنك الاطّلاع على الجهاز الإعداد: يفترض الجزء المتبقي من هذا البرنامج التعليمي أن لديك واجهة أوامر مفتوحة على بيئة TF.
للتبسيط، يوضح هذا البرنامج التعليمي إضافة تهيئة الفئات إلى المكتبة الأساسية لإطار عمل TF. ويمكن توسيع ذلك ليشمل تطوير خارج شجرة المصدر من خلال تجميع ملف JAR المتداول، ثم تجميع الوحدات مقابل JAR ذلك.
إنشاء صف اختبار (D)
لننشئ اختبار hello world الذي يفرغ فقط رسالة إلى stdout. حاسمة يقوم الاختبار المقايضة بشكل عام IRemoteTest من واجهة pyplot. في ما يلي طريقة تنفيذ اختبار 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
وإعادة إنشاء المقايضة من واجهة المستخدم:
m -jN
يُرجى العِلم أنّه يتم استخدام CLog.i
في المثال أعلاه لتوجيه المخرجات إلى وحدة التحكّم. المزيد
يمكنك الاطّلاع على معلومات حول تسجيل الدخول إلى الاتحاد التجاري في المقالة تسجيل (D، I، R).
إذا لم تنجح عملية الإنشاء، يُرجى الرجوع إلى الجهاز يمكنك إجراء عملية الإعداد لضمان عدم تفويت أي خطوة.
إنشاء تهيئة (I)
تصبح اختبارات الاتحاد التجاري قابلة للتنفيذ من خلال إنشاء التهيئة، وهي عبارة عن ملف XML الذي يقدم تعليمات حول إجراء الاختبار (أو الاختبارات) المطلوب إجراؤها، ومعرفة الوحدات الأخرى المطلوب تنفيذها طلبك.
لنبدأ في إنشاء تهيئة جديدة لـ HelloWorldTest (يرجى ملاحظة الصف الكامل اسم HelloWorldTest):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
يمكنك حفظ هذه البيانات في ملف helloworld.xml
في أي مكان على جهازك.
نظام الملفات (مثل /tmp/helloworld.xml
). سيقوم TF بتحليل
ملف XML الخاص بالإعداد (المعروف أيضًا باسم الضبط)، حمّل الفئة المحددة باستخدام
الانعكاس، وإنشاء مثيل له، وتحويله إلى IRemoteTest
، واستدعاء
run
.
تنفيذ الإعداد (R)
من واجهة المستخدم، ابدأ تشغيل وحدة التحكّم المبادلة:
tradefed.sh
يُرجى التأكُّد من اتصال الجهاز بالجهاز المضيف ورؤيته للمقايضة:
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!
من المفترض أن تظهر لك رسالة "مرحبًا، الناتج في الوحدة الطرفية.
يمكنك التأكّد من تنفيذ أحد الأوامر باستخدام list invocations
أو
l i
في مطالبة وحدة التحكم، ومن المفترض ألا تظهر أي نتائج. إذا كانت الأوامر حاليًا
قيد التشغيل، فإنها تعرض على النحو التالي:
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 نفسها. تتعرف أداة تبديل الوظيفة تلقائيًا على جميع الإعدادات الموضوعة في config على مسار classpath.
للتوضيح، انقل ملف helloworld.xml
إلى ملف التبادل.
المكتبة الأساسية
(<tree>/tools/tradefederation/core/res/config/example/helloworld.xml
).
أعدت تداول العملات، وأعد تشغيل وحدة التحكم المتداولة، ثم اطلب من trackfed عرض
قائمة الإعدادات من 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. مقايضة هو إجراء اختبارات باستخدام أجهزة Android، لذا يمكننا إضافة جهاز Android للاختبار.
يمكن أن تحصل الاختبارات على إشارة إلى جهاز Android باستخدام ميزة 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.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
التي يمكنك إعادة استخدامها.
بدلاً من كتابة وصفك من البداية على سبيل المثال:
اختبار قياس حالة التطبيق
إجراء اختبارات أحد تطبيقات Android عن بُعد على جهاز Android وتحليل
النتائج، وإعادة توجيه هذه النتائج إلى ITestInvocationListener
).
للحصول على التفاصيل، يمكنك مراجعة
الاختبار
الأنواع:
نتائج اختبار المتجر (I)
يتم تنفيذ أداة استماع الاختبار التلقائية لتهيئة TF: TextResultReporter، وهو ما يؤدي إلى تفريغ نتائج الاستدعاء إلى البيانات الثابتة. للتوضيح، قم بتشغيل إعدادات 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. لتحديد results_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>
الآن أعد بناء نموذج hello world وإعادة تشغيل نموذج 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 من واجهة pyplot.
يدعم تطبيق Tradefed العديد من المستمعين للاستدعاء، حتى تتمكن من إرسال نتائج الاختبار
إلى وجهات مستقلة متعددة للقيام بذلك، حدد فقط خيارات
علامات <result_reporter>
في الإعدادات.
مرافق قطع الأشجار (د، ي، ر)
تشمل مرافق التسجيل الخاصة بـ "TF" القدرة على:
- التقاط السجلّات من الجهاز (المعروف أيضًا باسم Logcat)
- تسجيل السجلات من إطار عمل اتحاد التجارة الذي يعمل على الجهاز المضيف (يُعرف أيضًا بسجلّ المضيف)
يلتقط إطار عمل TF تلقائيًا ملف Logcat من الجهاز المخصّص.
وترسلها إلى مستمع الاستدعاء لمعالجتها
بعد ذلك، يحفظ XmlResultReporter
ملف Logcat الذي تم التقاطه للجهاز.
يتم الإبلاغ عن سجلات مضيف TF باستخدام
برنامج تضمين CLog
لفئة سجل ddmlib. دعنا نحوّل
اتصال 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 …
بشكل تلقائي، يتم تبادل
إخراج سجل المضيف
الرسائل إلى 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 (المعروفة أيضًا باسم كائنات الإعدادات)
أيضًا تلقي بيانات من وسيطات سطر الأوامر من خلال استخدام
التعليق التوضيحي "@Option
"
للمشاركة، تطبِّق فئة عنصر الإعدادات @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 بعد أن
تم التبديل إلى استخدام FileLogger
. يمكنك زيادة الإسهاب
تسجيل الدخول إلى stdout من خلال إدخال وسيطة --log-level-display
.
جرِّب ذلك الآن، وستظهر الرسالة "لديّ جهاز" ظهور رسالة التسجيل مرة أخرى في stdout، بالإضافة إلى تسجيله في ملف:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
هذا كل شيء يا رفاق!
للتذكير، إذا واجهتك مشكلة ما، فإن تجارة يحتوي رمز مصدر الاتحاد على الكثير من المعلومات المفيدة التي لا يتم الكشف عنها في الوثائق. إذا لم ينجح كل ما سبق، يمكنك طرحه على نظام التشغيل Android مجموعة Google، مع "اتحاد تجاري" في موضوع الرسالة.