Bu eğitim, "Merhaba dünya" Trade Federation (Tradefed veya TF) test yapılandırması oluşturma konusunda size yol gösterir ve TF çerçevesine uygulamalı bir giriş sunar. Geliştirme ortamından başlayarak basit bir yapılandırma oluşturup özellikler ekleyeceksiniz.
Eğitim, test geliştirme sürecini bir dizi alıştırma olarak sunar. Her alıştırma, yapılandırmanızı nasıl oluşturacağınızı ve kademeli olarak nasıl hassaslaştıracağınızı gösteren birkaç adımdan oluşur. Test yapılandırmasını tamamlamak için ihtiyacınız olan tüm örnek kod sağlanmıştır ve her alıştırmanın başlığı, ilgili adımda yer alan rolleri açıklayan bir harfle ek açıklamaya sahiptir:
- Geliştirici için D
- Entegre eden için I
- Test çalıştırıcı için R
Eğitimi tamamladıktan sonra çalışan bir TF yapılandırmanız olur ve TF çerçevesindeki birçok önemli kavramı anlarsınız.
Ticaret Federasyonu'nu ayarlama
TF geliştirme ortamını ayarlamayla ilgili ayrıntılar için Makine Kurulumu başlıklı makaleyi inceleyin. Bu eğitimdeki diğer bölümlerde, TF ortamında başlatılmış bir kabuğunuz olduğu varsayılmaktadır.
Bu eğitimde, basitlik açısından bir yapılandırmanın ve sınıflarının TF çerçevesi ana kitaplığına eklenmesi gösterilmektedir. Bu, tradefed JAR'ı derleyip ardından modüllerinizi bu JAR'a göre derleyerek kaynak ağacının dışında modül geliştirmeye kadar genişletilebilir.
Test sınıfı oluşturma (D)
Yalnızca stdout'a bir mesaj yayan bir Merhaba Dünya testi oluşturalım. Tradefed testi genellikle IRemoteTest arayüzünü uygular. HelloWorldTest için bir uygulama aşağıda verilmiştir:
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
içine kaydedin ve kabuğunuzdan tradefed'i yeniden oluşturun:
m -jN
Yukarıdaki örnekte CLog.i
değerinin çıkışı konsola yönlendirmek için kullanıldığını unutmayın. Trade Federation'a giriş yapma hakkında daha fazla bilgi Günlük kaydı (D, I, R) bölümünde açıklanmıştır.
Derleme başarılı olmazsa bir adımı atlamadığınızdan emin olmak için Makine Kurulumu'na bakın.
Yapılandırma oluşturma (I)
Trade Federation testleri, tradefed'e hangi testin (veya testlerin) çalıştırılacağının yanı sıra hangi diğer modüllerin ve hangi sırayla çalıştırılacağını belirten bir yapılandırma (XML dosyası) oluşturularak çalıştırılabilir hale getirilir.
HelloWorldTest için yeni bir yapılandırma oluşturalım (HelloWorldTest sınıfının tam 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 bir helloworld.xml
dosyasına kaydedin (ör. /tmp/helloworld.xml
). TF, yapılandırma XML dosyasını (diğer adıyla config) ayrıştırır, yansımayı kullanarak belirtilen sınıfı yükler, sınıfı örneklendirir, IRemoteTest
olarak yayınlar ve run
yöntemini çağırır.
Yapılandırmayı çalıştırma (R)
Kabuğunuzdan tradefed konsolunu başlatın:
tradefed.sh
Bir cihazın ana makineye bağlı olduğundan ve tradefed tarafından görülebildiğinden emin olun:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Yapılandırmalar, run <config>
console komutu kullanılarak yürütülebilir. Bunu deneyin:
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!
Terminalde "Hello, TF World!" çıkışını görürsünüz.
Konsolda list invocations
veya l i
kullanarak bir komutun çalıştırıldığını onaylayabilirsiniz. Bu durumda hiçbir şey yazdırılmaz. Şu anda çalışan komutlar aşağıdaki gibi gösterilir:
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ı tradefed JAR'larına da ekleyebilirsiniz. Tradefed, sınıf yolu klasörlerindeki config klasörlerine yerleştirilen tüm yapılandırmaları otomatik olarak tanır.
Bunu açıklamak için helloworld.xml
dosyasını tradefed temel kitaplığına (<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 yolu klasöründeki yapılandırmaların listesini göstermesini isteyin:
tf> list configs […] example/helloworld: Runs the hello world test
Artık helloworld yapılandırmasını şunu 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şimde bulunma (D, R)
HelloWorldTest'imiz şimdilik ilginç bir şey yapmıyor. Tradefed'in uzmanlık alanı Android cihazları kullanarak test yürütmektir. Bu nedenle teste bir Android cihaz ekleyelim.
Testler, IRemoteTest#run
yöntemi çağrıldığında çerçeve tarafından sağlanan TestInformation
öğesini kullanarak bir Android cihaz referansı alabilir.
HelloWorldTest baskı mesajını, cihazın seri numarasını gösterecek şekilde değiştirelim:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
Ardından tradefed'i yeniden oluşturun ve cihaz listesini kontrol edin:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Kullanılabilir olarak listelenen seri numarasını not edin. Bu, HelloWorld'a atanması gereken cihazdır:
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 baskı mesajını görürsünüz.
Test sonuçlarını gönder (D)
IRemoteTest
, #run
yöntemine sağlanan ITestInvocationListener örneğinde yöntemler çağırarak sonuçları raporlar. Her çağrının başlangıcını (ITestInvocationListener#invocationStarted aracılığıyla) ve sonunu (ITestInvocationListener#invocationEnded aracılığıyla) bildirmekten TF çerçevesi sorumludur.
Test çalıştırma, mantıksal bir test koleksiyonudur. Test sonuçlarını bildirmek için IRemoteTest
, test çalıştırmasının başlangıcını, her testin başlangıç ve bitiş zamanını ve test çalıştırmasının bitişini bildirmekten sorumludur.
Tek bir başarısız test sonucuyla HelloWorldTest uygulamasının nasıl görünebileceği aşağıda gösterilmektedir.
@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, sıfırdan kendi uygulamanızı yazmak yerine yeniden kullanabileceğiniz çeşitli IRemoteTest
uygulamaları içerir. Örneğin, InstrumentationTest, bir Android uygulamasının testlerini Android cihazda uzaktan çalıştırabilir, sonuçları ayrıştırabilir ve bu sonuçları ITestInvocationListener
) iletebilir. Ayrıntılar için Test Türleri bölümüne bakın.
Mağaza testi sonuçları (I)
TF yapılandırması için varsayılan test dinleyicisi uygulaması, bir çağrının sonuçlarını stdout'a aktaran TextResultReporter'dır. Bunu açıklamak için ö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 (ör. bir dosyada) depolamak için yapılandırmanızda result_reporter
etiketini kullanarak özel bir ITestInvocationListener
uygulaması belirtin.
TF, test sonuçlarını ant JUnit XML yazıcısı tarafından kullanılana benzer bir biçimde bir XML dosyasına yazan XmlResultReporter dinleyicisini de içerir. Yapılandırmada result_reporter parametresini belirtmek için …/res/config/example/helloworld.xml
config dosyası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>
Artık tradefed'i yeniden oluşturun ve hello world ö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ı oluşturulduğunu belirten günlük mesajına dikkat edin. Oluşturulan dosya şu şekilde görünür:
<?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>
Kendi özel çağrı dinleyicilerinizi de yazabilirsiniz. Bunun için ITestInvocationListener arayüzünü uygulamanız yeterlidir.
Tradefed, birden fazla çağrı dinleyicisini destekler. Böylece test sonuçlarını birden fazla bağımsız hedefe gönderebilirsiniz. Bunun için yapılandırmanızda birden fazla <result_reporter>
etiketi belirtmeniz yeterlidir.
Günlük kaydı tesisleri (D, I, R)
TF'nin günlük kaydı özellikleri şunları içerir:
- Cihazdan günlükleri yakalama (diğer adıyla cihaz logcat'i)
- Ana makinede çalışan Trade Federation çerçevesinden günlükleri kaydetme (diğer adıyla ana makine günlüğü)
TF çerçevesi, ayrılan cihazdan logcat'i otomatik olarak yakalar ve işlenmek üzere çağrı dinleyicisine gönderir.
XmlResultReporter
, yakalanan cihaz günlük kaydını dosya olarak kaydeder.
TF ana makine 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ı 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
'a benzer şekilde dize eklemeyi doğrudan işler. TF'yi yeniden oluşturup yeniden çalıştırdığınızda stdout'da aşağıdaki günlük mesajını görürsünüz:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
tradefed varsayılan olarak ana makine günlük mesajlarını stdout'a gönderir. TF, mesajları bir dosyaya yazan bir günlük uygulaması da içerir: FileLogger.
Dosya günlüğe kaydını eklemek için yapılandırmaya logger
etiketi ekleyin ve FileLogger
sınıfının tam adını belirtin:
<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>
Ardından, helloworld örneğini yeniden derleyip ç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ı, ana makine günlüğünün yolunu belirtir. Bu yol görüntülendiğinde HelloWorldTest günlük mesajınızı içermelidir:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
Örnek çıkış:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
İşleme seçenekleri (D, I, R)
TF yapılandırmasından yüklenen nesneler (diğer adıyla yapılandırma nesneleri), @Option
ek açıklamaları kullanılarak komut satırı bağımsız değişkenlerinden de veri alabilir.
Katılım için bir Yapılandırma nesnesi sınıfı, @Option
ek açıklamasını bir üye alanına uygular ve alana benzersiz bir ad verir. Bu, üye alan değerinin bir komut satırı seçeneğiyle doldurulmasını sağlar (ayrıca bu seçeneği yapılandırma yardım sistemine otomatik olarak ekler).
Not: Tüm alan türleri desteklenmez. Desteklenen türlerin açıklaması için OptionSetter'a bakın.
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";
Ardından, HelloWorldTest işlevindeki seçeneğin değerini doğru şekilde aldığını göstermek için bir günlük mesajı ekleyelim:
@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 dosyasını çalıştırın. my_option
varsayılan değerini içeren bir günlük mesajı göreceksiniz:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
Komut satırından değer aktarma
my_option
için bir değer iletin. my_option
, bu değerle doldurulur:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
TF yapılandırmaları, @Option
alanları için otomatik olarak yardım metni gösteren bir yardım sistemi de içerir. Hemen deneyin. my_option
ile ilgili yardım metnini görürsünüz:
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çenekleri yazdırma" mesajını not edin. TF, seçenek yardım metinlerinin karmaşıklığını azaltmak için --help
belirtildiğinde belirli bir @Option
alan yardım metninin gösterilip gösterilmeyeceğini belirlemek üzere Option#importance
özelliğini kullanır. --help-all
, önem düzeyine bakılmaksızın tüm @Option
alanları için her zaman yardım gösterir. Ayrıntılar için Option.Importance konusuna bakın.
Bir yapılandırmadan değer iletme
<option name="" value="">
öğesi ekleyerek yapılandırmada bir Option değeri de belirtebilirsiniz. helloworld.xml
ile test edin:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
helloworld dosyasını yeniden derleyip çalıştırdığınızda şu çıkışı elde edersiniz:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
Yapılandırma yardımı da my_option
için varsayılan değeri gösterecek şekilde güncellenir:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
helloworld yapılandırmasına dahil edilen diğer yapılandırma nesneleri (ör. FileLogger
) de seçenekleri kabul eder. --log-level-display
seçeneği, stdout'da görünen günlükleri filtrelediği için ilgi çekicidir. Eğitimin başlarında "Merhaba, TF Dünyası! FileLogger
kullanmaya başladıktan sonra "I have device …" günlük mesajı stdout'da gösterilmeyi durdurdu. --log-level-display
bağımsız değişkenini ileterek stdout'a günlük kaydının ayrıntı düzeyini artırabilirsiniz.
Bunu şimdi deneyin. "Cihazım var" günlük mesajının bir dosyaya kaydedilmesinin yanı sıra stdout'da tekrar göründüğünü göreceksiniz:
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.
Bir konuda takılırsanız Trade Federation kaynak kodunda dokümanda yer almayan birçok yararlı bilgi olduğunu hatırlatmak isteriz. Tüm yöntemler işe yaramazsa android-platform Google Grubu'nda "Trade Federation" ileti öznesini kullanarak soru sormayı deneyin.