Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Ví dụ kiểm tra TF từ đầu đến cuối

Hướng dẫn này hướng dẫn bạn cách tạo cấu hình kiểm tra "hello world" Trade Federation (TF) và cung cấp cho bạn phần giới thiệu thực tế về khung TF. Bắt đầu từ môi trường phát triển, bạn sẽ tạo một cấu hình đơn giản và thêm các tính năng.

Hướng dẫn trình bày quá trình phát triển thử nghiệm dưới dạng một tập hợp các bài tập, mỗi bài bao gồm một số bước, trình bày cách xây dựng và dần dần tinh chỉnh cấu hình của bạn. Tất cả mã mẫu bạn cần để hoàn thành cấu hình thử nghiệm được cung cấp và tiêu đề của mỗi bài tập được chú thích bằng một chữ cái mô tả các vai trò liên quan đến bước đó:

  • D dành cho nhà phát triển
  • Tôi cho Người tích hợp
  • R dành cho người chạy thử nghiệm

Sau khi hoàn thành hướng dẫn, bạn sẽ có cấu hình TF hoạt động và hiểu nhiều khái niệm quan trọng trong khung TF.

Thành lập Liên đoàn Thương mại

Để biết chi tiết về cách thiết lập môi trường phát triển TF, hãy xem Thiết lập Máy . Phần còn lại của hướng dẫn này giả sử bạn có một trình bao đang mở đã được khởi tạo vào môi trường TF.

Để đơn giản, hướng dẫn này minh họa việc thêm cấu hình và các lớp của nó vào thư viện lõi khung TF. Điều này có thể được mở rộng để phát triển các mô-đun bên ngoài cây nguồn bằng cách biên dịch JAR đã đánh đổi, sau đó biên dịch các mô-đun của bạn dựa trên JAR đó.

Tạo một lớp thử nghiệm (D)

Hãy tạo một bài kiểm tra hello world chỉ gửi một thông báo vào stdout. Thử nghiệm tradefed thường triển khai giao diện IRemoteTest . Đây là cách triển khai cho 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!");
    }
}

Lưu mã mẫu này vào <tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java và xây dựng lại tradefed từ shell của bạn:

m -jN

Lưu ý rằng CLog.i trong ví dụ trên được sử dụng để chuyển đầu ra trực tiếp đến bảng điều khiển. Thông tin thêm về đăng nhập Trade Federation được mô tả trong Ghi nhật ký (D, I, R) .

Nếu quá trình xây dựng không thành công, hãy tham khảo Thiết lập Máy để đảm bảo bạn không bỏ lỡ một bước nào.

Tạo cấu hình (I)

Các bài kiểm tra của Trade Federation được thực hiện bằng cách tạo một Cấu hình , một tệp XML hướng dẫn tradefed chạy bài kiểm tra nào (hoặc các bài kiểm tra), cũng như các mô-đun khác sẽ thực thi và theo thứ tự nào.

Hãy tạo một cấu hình mới cho HelloWorldTest của chúng tôi (lưu ý tên lớp đầy đủ của HelloWorldTest):

<configuration description="Runs the hello world test">
    <test class="com.android.tradefed.example.HelloWorldTest" />
</configuration>

Lưu dữ liệu này vào tệp helloworld.xml ở bất kỳ đâu trên hệ thống tệp cục bộ của bạn (ví dụ: /tmp/helloworld.xml ). TF sẽ phân tích cú pháp tệp XML cấu hình (hay còn gọi là cấu hình ), tải lớp được chỉ định bằng cách sử dụng phản chiếu, khởi tạo nó, truyền nó tới IRemoteTest và gọi phương thức run của nó.

Chạy cấu hình (R)

Từ shell của bạn, khởi chạy bảng điều khiển tradefed:

tradefed.sh

Đảm bảo một thiết bị được kết nối với máy chủ và hiển thị với tradefed:

tf> list devices
Serial            State      Product   Variant   Build   Battery
004ad9880810a548  Available  mako      mako      JDQ39   100

Các cấu hình có thể được thực thi bằng lệnh run <config> console. Thử:

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!

Bạn sẽ thấy "Xin chào, TF World!" đầu ra trên thiết bị đầu cuối.

Bạn có thể xác nhận rằng một lệnh đã chạy xong bằng cách sử dụng lệnh list invocations hoặc li trong dấu nhắc bảng điều khiển và lệnh đó sẽ không in gì. Nếu các lệnh hiện đang chạy, chúng sẽ hiển thị như sau:

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}'

Thêm cấu hình vào classpath (D, I, R)

Để thuận tiện cho việc triển khai, bạn cũng có thể gộp các cấu hình vào chính các JAR đã được trao đổi. Tradefed tự động nhận dạng tất cả các cấu hình được đặt trong các thư mục cấu hình trên classpath.

Để minh họa, hãy di chuyển tệp helloworld.xml vào thư viện lõi tradefed ( <tree>/tools/tradefederation/core/res/config/example/helloworld.xml ). Xây dựng lại tradefed, khởi động lại bảng điều khiển tradefed, sau đó yêu cầu tradefed hiển thị danh sách các cấu hình từ classpath:

tf> list configs
[…]
example/helloworld: Runs the hello world test

Bây giờ bạn có thể chạy cấu hình helloworld bằng cách sử dụng:

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!

Tương tác với thiết bị (D, R)

Cho đến nay, HelloWorldTest của chúng tôi không làm bất cứ điều gì thú vị. Chuyên môn của Tradefed là chạy thử nghiệm bằng thiết bị Android, vì vậy hãy thêm thiết bị Android vào thử nghiệm.

Các bài kiểm tra có thể nhận tham chiếu đến thiết bị Android bằng cách sử dụng TestInformation , được cung cấp bởi khuôn khổ khi phương thức IRemoteTest#run được gọi.

Hãy sửa đổi thông báo in HelloWorldTest để hiển thị số sê-ri của thiết bị:

@Override
public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException {
    CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber());
}

Bây giờ xây dựng lại tradefed và kiểm tra danh sách các thiết bị:

tradefed.sh
tf> list devices
Serial            State      Product   Variant   Build   Battery
004ad9880810a548  Available  mako      mako      JDQ39   100

Ghi lại số sê-ri được liệt kê là Có sẵn ; đó là thiết bị nên được phân bổ cho 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

Bạn sẽ thấy thông báo in mới hiển thị số sê-ri của thiết bị.

Gửi kết quả kiểm tra (D)

IRemoteTest báo cáo kết quả bằng cách gọi các phương thức trên cá thể ITestInvocationListener được cung cấp cho phương thức #run . Bản thân khung TF chịu trách nhiệm báo cáo sự bắt đầu (qua ITestInvocationListener # invocationStarted ) và kết thúc (qua ITestInvocationListener # invocationEnded ) của mỗi Lời mời.

Chạy thử nghiệm là một tập hợp các thử nghiệm hợp lý. Để báo cáo kết quả thử nghiệm, IRemoteTest chịu trách nhiệm báo cáo thời điểm bắt đầu chạy thử nghiệm, bắt đầu và kết thúc mỗi thử nghiệm và kết thúc quá trình chạy thử nghiệm.

Đây là cách triển khai HelloWorldTest có thể trông như thế nào với một kết quả thử nghiệm không thành công.

@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 bao gồm một số triển khai IRemoteTest mà bạn có thể sử dụng lại thay vì viết của riêng bạn từ đầu. Ví dụ: InstrumentationTest có thể chạy các bài kiểm tra của ứng dụng Android từ xa trên thiết bị Android, phân tích cú pháp kết quả và chuyển tiếp các kết quả đó đến ITestInvocationListener ). Để biết chi tiết, hãy xem Các loại kiểm tra .

Lưu trữ kết quả kiểm tra (I)

Việc triển khai trình nghe kiểm tra mặc định cho cấu hình TF là TextResultReporter , kết xuất kết quả của một lời gọi đến stdout. Để minh họa, hãy chạy cấu hình HelloWorldTest từ phần trước:

./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

Để lưu trữ kết quả của một lời gọi ở nơi khác, chẳng hạn như trong một tệp, hãy chỉ định triển khai ITestInvocationListener tùy chỉnh bằng cách sử dụng thẻ result_reporter trong cấu hình của bạn.

TF cũng bao gồm trình nghe XmlResultReporter ghi kết quả kiểm tra vào tệp XML ở định dạng tương tự như định dạng được sử dụng bởi trình viết XML kiến ​​JUnit. Để chỉ định result_reporter trong cấu hình, hãy chỉnh sửa cấu hình …/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>

Bây giờ xây dựng lại tradefed và chạy lại mẫu 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

Lưu ý thông báo nhật ký cho biết rằng một tệp XML đã được tạo; tệp được tạo sẽ trông giống như sau:

<?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>

Bạn cũng có thể viết trình nghe lời gọi tùy chỉnh của riêng mình — họ chỉ cần triển khai giao diện ITestInvocationListener .

Tradefed hỗ trợ nhiều trình nghe lời gọi, vì vậy bạn có thể gửi kết quả kiểm tra đến nhiều đích độc lập. Để làm điều này, chỉ cần chỉ định nhiều <result_reporter> trong cấu hình của bạn.

Ghi nhật ký (D, I, R)

Các phương tiện ghi nhật ký của TF bao gồm khả năng:

  1. Chụp nhật ký từ thiết bị (còn gọi là logcat thiết bị)
  2. Ghi lại nhật ký từ khung Trade Federation đang chạy trên máy chủ (hay còn gọi là nhật ký máy chủ)

Khung TF tự động bắt logcat từ thiết bị được cấp phát và gửi nó đến trình lắng nghe yêu cầu để xử lý. Sau đó, XmlResultReporter sẽ lưu logcat của thiết bị đã chụp dưới dạng tệp.

Nhật ký máy chủ TF được báo cáo bằng cách sử dụng trình bao bọc CLog cho lớp Nhật ký ddmlib. Hãy chuyển đổi lệnh gọi System.out.println trước đó trong HelloWorldTest thành lệnh gọi CLog :

@Override
public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
    CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());

CLog xử lý nội suy chuỗi trực tiếp, tương tự như String.format . Khi bạn xây dựng lại và chạy lại TF, bạn sẽ thấy thông báo nhật ký trên stdout:

tf> run example/helloworld
…
05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
…

Theo mặc định, tradefed xuất thông báo nhật ký máy chủ sang stdout . TF cũng bao gồm một triển khai nhật ký ghi thông báo vào một tệp: FileLogger . Để thêm ghi nhật ký tệp, hãy thêm thẻ ghi nhật ký vào cấu hình, chỉ định tên lớp đầy đủ FileLogger logger

<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>

Bây giờ, hãy xây dựng lại và chạy lại ví dụ 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
…

Thông báo nhật ký cho biết đường dẫn của nhật ký máy chủ, khi được xem, sẽ chứa thông báo nhật ký HelloWorldTest của bạn:

more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt

Ví dụ đầu ra:

…
05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548

Các tùy chọn xử lý (D, I, R)

Các đối tượng được tải từ Cấu hình TF (còn gọi là đối tượng Cấu hình ) cũng có thể nhận dữ liệu từ các đối số dòng lệnh thông qua việc sử dụng chú thích @Option .

Để tham gia, lớp đối tượng Cấu hình áp dụng chú thích @Option cho trường thành viên và cung cấp cho nó một tên duy nhất. Điều này cho phép giá trị trường thành viên đó được điền thông qua tùy chọn dòng lệnh (và cũng tự động thêm tùy chọn đó vào hệ thống trợ giúp cấu hình).

Lưu ý: Không phải tất cả các loại trường đều được hỗ trợ. Để biết mô tả về các loại được hỗ trợ, hãy xem OptionSetter .

Hãy thêm @Option vào 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";

Tiếp theo, hãy thêm thông báo nhật ký để hiển thị giá trị của tùy chọn trong HelloWorldTest để chúng tôi có thể chứng minh rằng nó đã được nhận chính xác:

@Override
public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
    …
    CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);

Cuối cùng, xây dựng lại TF và chạy helloworld; bạn sẽ thấy một thông báo nhật ký với giá trị mặc định my_option :

tf> run example/helloworld
…
05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'

Truyền các giá trị từ dòng lệnh

Chuyển một giá trị cho my_option ; bạn sẽ thấy my_option điền với giá trị đó:

tf> run example/helloworld --my_option foo
…
05-24 18:33:44 I/HelloWorldTest: I received option 'foo'

Cấu hình TF cũng bao gồm một hệ thống trợ giúp, tự động hiển thị văn bản trợ giúp cho các trường @Option . Hãy thử ngay bây giờ và bạn sẽ thấy văn bản trợ giúp cho 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.

Lưu ý thông báo về "chỉ in các tùy chọn quan trọng." Để giảm bớt sự lộn xộn của trợ giúp tùy chọn, TF sử dụng thuộc tính Option#importance để xác định xem có hiển thị văn bản trợ giúp trường @Option cụ thể hay không khi --help được chỉ định. --help-all luôn hiển thị trợ giúp cho tất cả các trường @Option , bất kể mức độ quan trọng. Để biết chi tiết, hãy xem Tùy chọn .

Chuyển các giá trị từ một cấu hình

Bạn cũng có thể chỉ định giá trị Tùy chọn trong cấu hình bằng cách thêm phần tử <option name="" value=""> . Kiểm tra nó bằng cách sử dụng helloworld.xml :

<test class="com.android.tradefed.example.HelloWorldTest" >
    <option name="my_option" value="fromxml" />
</test>

Việc xây dựng lại và vận hành helloworld bây giờ sẽ tạo ra đầu ra này:

05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'

Trợ giúp cấu hình cũng nên cập nhật để chỉ ra giá trị mặc định của my_option :

tf> run example/helloworld --help
  test options:
    -m, --my_option      this is the option's help text Default: fromxml.

Các đối tượng cấu hình khác có trong cấu hình helloworld, chẳng hạn như FileLogger , cũng chấp nhận các tùy chọn. Tùy chọn --log-level-display rất thú vị vì nó lọc các bản ghi hiển thị trên stdout. Trước đó trong hướng dẫn, bạn có thể đã nhận thấy thông báo nhật ký "Xin chào, TF World! Tôi có thiết bị ..." ngừng hiển thị trên stdout sau khi chúng tôi chuyển sang sử dụng FileLogger . Bạn có thể tăng mức độ chi tiết của việc ghi nhật ký vào stdout bằng cách chuyển vào --log-level-display arg.

Hãy thử điều này ngay bây giờ và bạn sẽ thấy thông báo nhật ký 'Tôi có thiết bị' xuất hiện lại trên stdout, ngoài việc được ghi vào một tệp:

tf> run example/helloworld --log-level-display info
…
05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548

Đó là tất cả, folks!

Xin nhắc lại, nếu bạn đang gặp khó khăn về vấn đề gì đó, mã nguồn của Trade Federation có rất nhiều thông tin hữu ích không được tiết lộ trong tài liệu. Nếu vẫn thất bại, hãy thử hỏi trên Nhóm Google nền tảng android , với "Liên đoàn thương mại" trong chủ đề thư.