Bu eğitim, bir "merhaba dünya" Ticaret Federasyonu (Tradefed veya TF) test yapılandırması oluşturma konusunda size rehberlik eder ve TF çerçevesine uygulamalı bir giriş sağlar. Bir geliştirme ortamından başlayarak basit bir yapılandırma oluşturacak ve özellikler ekleyeceksiniz.
Öğretici, test geliştirme sürecini, yapılandırmanızı nasıl oluşturacağınızı ve kademeli olarak iyileştireceğinizi gösteren, her biri birkaç adımdan oluşan bir dizi alıştırma olarak sunar. Test yapılandırmasını tamamlamak için ihtiyacınız olan tüm örnek kodlar sağlanmıştır ve her alıştırmanın başlığı, o adımdaki rolleri açıklayan bir harfle açıklanmıştır:
- Geliştirici için D
- Entegratör için ben
- Test Çalıştırıcısı için R
Eğitimi tamamladıktan sonra işleyen bir TF yapılandırmasına sahip olacak ve TF çerçevesindeki birçok önemli kavramı anlayacaksınız.
Ticaret Federasyonu'nu kurun
TF geliştirme ortamını ayarlamaya ilişkin ayrıntılar için bkz. Makine Kurulumu . Bu eğitimin geri kalanında, TF ortamına başlatılmış açık bir kabuğunuz olduğu varsayılmaktadır.
Basitlik açısından bu eğitimde, bir konfigürasyonun ve sınıflarının TF çerçeve çekirdek kütüphanesine eklenmesi gösterilmektedir. Bu, ticari olarak beslenen JAR'ın derlenmesi ve ardından modüllerinizin bu JAR'a göre derlenmesi yoluyla kaynak ağacın dışında modüller geliştirmeye kadar genişletilebilir.
Bir test sınıfı oluşturun (D)
Stdout'a mesaj gönderen bir merhaba dünya testi oluşturalım. Ticareti yapılan bir test genellikle IRemoteTest arayüzünü uygular. İşte HelloWorldTest için bir uygulama:
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!"); } }
Bu örnek kodu <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
dosyasına kaydedin ve tradefed'i kabuğunuzdan yeniden oluşturun:
m -jN
Yukarıdaki örnekte CLog.i
çıktıyı konsola yönlendirmek için kullanıldığını unutmayın. Ticaret Federasyonu'nda oturum açma hakkında daha fazla bilgi Günlüğe Kaydetme (D, I, R) bölümünde açıklanmıştır.
Derleme başarılı olmazsa, hiçbir adımı kaçırmadığınızdan emin olmak için Makine Kurulumu'na başvurun.
Bir konfigürasyon oluşturun (I)
Ticaret Federasyonu testleri, tradefed'e hangi testin (veya testlerin) çalıştırılacağı ve diğer hangi modüllerin hangi sırayla çalıştırılacağı konusunda talimat veren bir XML dosyası olan bir Yapılandırma oluşturularak yürütülebilir hale getirilir.
HelloWorldTest'imiz için yeni bir Konfigürasyon oluşturalım (HelloWorldTest'in tam sınıf adını not edin):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
Bu verileri yerel dosya sisteminizin herhangi bir yerindeki helloworld.xml
dosyasına kaydedin (örn /tmp/helloworld.xml
). TF, Yapılandırma XML dosyasını (diğer adıyla config ) ayrıştıracak, yansımayı kullanarak belirtilen sınıfı yükleyecek, somutlaştıracak, IRemoteTest
aktaracak ve run
yöntemini çağıracaktır.
Yapılandırmayı çalıştırın (R)
Kabuğunuzdan takas edilen konsolu başlatın:
tradefed.sh
Bir cihazın ana makineye bağlı olduğundan ve takas için görünür olduğundan emin olun:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Yapılandırmalar run <config>
konsol komutu kullanılarak yürütülebilir. Denemek:
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!
"Merhaba, TF Dünyası!" görmelisiniz. terminaldeki çıktı.
Konsol komut isteminde list invocations
veya li
kullanarak bir komutun çalışmasının tamamlandığını doğrulayabilirsiniz ve komut hiçbir şey yazdırmamalıdır. Komutlar şu anda çalışıyorsa aşağıdaki gibi görüntülenirler:
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}'
Yapılandırmayı sınıf yoluna ekleyin (D, I, R)
Dağıtım kolaylığı için, yapılandırmaları ticareti yapılan JAR'ların kendisinde de paketleyebilirsiniz. Tradefed, sınıf yolundaki yapılandırma klasörlerine yerleştirilen tüm yapılandırmaları otomatik olarak tanır.
Örnek olarak helloworld.xml
dosyasını ticari beslenen çekirdek kitaplığa ( <tree>/tools/tradefederation/core/res/config/example/helloworld.xml
) taşıyın. Tradefed'i yeniden oluşturun, tradefed konsolunu yeniden başlatın ve ardından tradefed'den sınıf yolundaki yapılandırmaların listesini görüntülemesini isteyin:
tf> list configs […] example/helloworld: Runs the hello world test
Artık helloworld yapılandırmasını aşağıdakileri kullanarak çalıştırabilirsiniz:
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!
Bir cihazla etkileşim kurun (D, R)
Şu ana kadar HelloWorldTest'imiz ilginç bir şey yapmıyor. Tradefed'in uzmanlığı Android cihazları kullanarak testler yürütmektir, bu yüzden teste bir Android cihazı ekleyelim.
Testler, IRemoteTest#run
yöntemi çağrıldığında çerçeve tarafından sağlanan TestInformation
kullanılarak bir Android cihazına referans alabilir.
Cihazın seri numarasını görüntülemek için HelloWorldTest yazdırma mesajını değiştirelim:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
Şimdi tradefed'i yeniden oluşturun ve cihazların listesini kontrol edin:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Mevcut olarak listelenen seri numarasını not edin; HelloWorld'e tahsis edilmesi gereken cihaz budur:
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
Cihazın seri numarasını gösteren yeni yazdırma mesajını görmelisiniz.
Test sonuçlarını gönder (D)
IRemoteTest
#run
yöntemine sağlanan ITestInvokasyonListener örneğindeki yöntemleri çağırarak sonuçları raporlar. TF çerçevesinin kendisi, her Çağrının başlangıcını ( ITestInvokasyonListener#invokasyonStarted aracılığıyla) ve sonunu ( ITestInvokasyonListener#invokasyonEnded aracılığıyla) raporlamaktan sorumludur.
Test çalıştırması , testlerin mantıksal bir koleksiyonudur. Test sonuçlarını raporlamak için IRemoteTest
, bir test çalışmasının başlangıcını, her testin başlangıcını ve bitişini ve test çalışmasının sonunu raporlamaktan sorumludur.
Tek bir başarısız test sonucuyla HelloWorldTest uygulamasının nasıl görünebileceği aşağıda açıklanmıştır.
@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, kendi uygulamanızı sıfırdan yazmak yerine yeniden kullanabileceğiniz çeşitli IRemoteTest
uygulamalarını içerir. Örneğin InstrumentationTest , bir Android uygulamasının testlerini bir Android cihazında uzaktan çalıştırabilir, sonuçları ayrıştırabilir ve bu sonuçları ITestInvocationListener
iletebilir. Ayrıntılar için bkz. Test Türleri .
Test sonuçlarını saklayın (I)
Bir TF yapılandırması için varsayılan test dinleyicisi uygulaması, bir çağrının sonuçlarını stdout'a döken TextResultReporter'dır . Örnek olarak önceki bölümdeki HelloWorldTest yapılandırmasını çalıştırın:
./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
Bir çağrının sonuçlarını başka bir yerde, örneğin bir dosyada saklamak için, yapılandırmanızdaki result_reporter
etiketini kullanarak özel bir ITestInvocationListener
uygulaması belirtin.
TF ayrıca, test sonuçlarını JUnit XML yazıcısının kullandığı formata benzer bir formatta bir XML dosyasına yazan XmlResultReporter dinleyicisini de içerir. Sonuç_raporlayıcısını yapılandırmada belirtmek için …/res/config/example/helloworld.xml
yapılandırmasını düzenleyin:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
Şimdi tradefed'i yeniden oluşturun ve merhaba dünya örneğini yeniden çalıştırın:
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
Bir XML dosyasının oluşturulduğunu belirten günlük mesajına dikkat edin; oluşturulan dosya şöyle görünmelidir:
<?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>
Ayrıca kendi özel çağrı dinleyicilerinizi de yazabilirsiniz; onların yalnızca ITestInvokasyonListener arayüzünü uygulaması yeterlidir.
Tradefed birden fazla çağrı dinleyicisini destekler, böylece test sonuçlarını birden fazla bağımsız hedefe gönderebilirsiniz. Bunu yapmak için yapılandırmanızda birden fazla <result_reporter>
etiketi belirtmeniz yeterlidir.
Günlük kaydı olanakları (D, I, R)
TF'nin kayıt olanakları şunları içerir:
- Cihazdan günlükleri yakalayın (diğer adıyla cihaz logcat'i)
- Ana makinede çalışan Ticaret Federasyonu çerçevesindeki günlükleri kaydedin (ana bilgisayar günlüğü olarak da bilinir)
TF çerçevesi, tahsis edilen cihazdan logcat'i otomatik olarak yakalar ve işlenmek üzere çağrı dinleyicisine gönderir. XmlResultReporter
daha sonra yakalanan cihazın logcat'ını bir dosya olarak kaydeder.
TF ana bilgisayar günlükleri, ddmlib Log sınıfı için CLog sarmalayıcısı kullanılarak raporlanır. HelloWorldTest'teki önceki System.out.println
çağrısını bir CLog
çağrısına dönüştürelim:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
String.format
benzer şekilde dize enterpolasyonunu doğrudan işler. TF'yi yeniden oluşturup yeniden çalıştırdığınızda stdout'ta günlük mesajını görmelisiniz:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
Varsayılan olarak, tradefed ana bilgisayar günlük mesajlarını stdout'a çıkarır . TF ayrıca mesajları bir dosyaya yazan bir günlük uygulamasını da içerir: FileLogger . Dosya günlüğü eklemek için yapılandırmaya FileLogger
tam sınıf adını belirten bir logger
etiketi ekleyin:
<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>
Şimdi helloworld örneğini yeniden oluşturun ve çalıştırın:
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 …
Günlük mesajı, görüntülendiğinde HelloWorldTest günlük mesajınızı içermesi gereken ana bilgisayar günlüğünün yolunu belirtir:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
Örnek çıktı:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
Kullanım seçenekleri (D, I, R)
TF Yapılandırmasından yüklenen nesneler (diğer adıyla Yapılandırma nesneleri ), @Option
ek açıklamasını kullanarak komut satırı bağımsız değişkenlerinden de veri alabilir.
Katılmak için bir Yapılandırma nesne sınıfı, @Option
ek açıklamasını bir üye alanına uygular ve ona benzersiz bir ad sağlar. Bu, üye alan değerinin bir komut satırı seçeneği aracılığıyla doldurulmasını sağlar (ve ayrıca bu seçeneği otomatik olarak yapılandırma yardım sistemine ekler).
Not: Tüm alan türleri desteklenmez. Desteklenen türlerin açıklaması için bkz. OptionSetter .
HelloWorldTest'e bir @Option
ekleyelim:
@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";
Daha sonra, seçeneğin değerini HelloWorldTest'te görüntülemek için bir günlük mesajı ekleyelim, böylece seçeneğin doğru şekilde alındığını gösterebiliriz:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
Son olarak TF'yi yeniden oluşturun ve helloworld'ü çalıştırın; my_option
varsayılan değerine sahip bir günlük mesajı görmelisiniz:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
Değerleri komut satırından iletin
my_option
için bir değer girin; my_option
bu değerle doldurulduğunu görmelisiniz:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
TF yapılandırmaları ayrıca @Option
alanları için yardım metnini otomatik olarak görüntüleyen bir yardım sistemi içerir. Şimdi deneyin; my_option
için yardım metnini görmelisiniz:
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.
"Yalnızca önemli seçeneklerin yazdırılması" hakkındaki iletiye dikkat edin. Seçenek yardım karmaşasını azaltmak için TF, --help
belirtildiğinde belirli bir @Option
alanı yardım metninin gösterilip gösterilmeyeceğini belirlemek için Option#importance
özelliğini kullanır. --help-all
önemi ne olursa olsun her zaman tüm @Option
alanları için yardımı gösterir. Ayrıntılar için bkz . Option.Importance .
Bir konfigürasyondan değerleri iletme
Ayrıca, bir <option name="" value="">
öğesi ekleyerek yapılandırma içinde bir Option değeri de belirleyebilirsiniz. helloworld.xml
kullanarak test edin:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
Helloworld'ü yeniden oluşturmak ve çalıştırmak artık şu çıktıyı üretmelidir:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
Yapılandırma yardımının da my_option
öğesinin varsayılan değerini gösterecek şekilde güncellenmesi gerekir:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
Helloworld yapılandırmasında yer alan FileLogger
gibi diğer yapılandırma nesneleri de seçenekleri kabul eder. --log-level-display
seçeneği ilginçtir çünkü stdout'ta görünen günlükleri filtreler. Eğitimin başlarında, FileLogger
kullanmaya geçtikten sonra "Merhaba, TF Dünyası! Cihazım var…' günlük mesajının stdout'ta görüntülenmediğini fark etmiş olabilirsiniz --log-level-display
arg.
Bunu şimdi deneyin; bir dosyada oturum açmanın yanı sıra 'Cihazım var' günlük mesajının stdout'ta yeniden göründüğünü görmelisiniz:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
Hepsi bu kadar millet!
Bir hatırlatma olarak, eğer bir konuda takılıp kalırsanız, Ticaret Federasyonu kaynak kodunda belgelerde gösterilmeyen birçok yararlı bilgi bulunur. Her şey başarısız olursa, mesaj konusuna "Ticaret Federasyonu" yazarak android platformundaki Google Grubuna sormayı deneyin.