Viết trình chạy kiểm thử IRemoteTest được phân đoạn

Khi viết trình chạy kiểm thử, bạn cần cân nhắc khả năng mở rộng. Hãy tự hỏi: "Nếu trình chạy kiểm thử của tôi phải chạy 200.000 trường hợp kiểm thử thì sẽ mất bao lâu?".

Phân mảnh là một trong những câu trả lời có trong Trade Federation. Bạn cần chia tất cả các kiểm thử mà trình chạy cần thành nhiều phần có thể chạy song song.

Trang này mô tả cách tạo trình chạy có thể phân mảnh cho Tradefed.

Giao diện cần triển khai

Giao diện quan trọng nhất cần triển khai để TF coi là có thể phân mảnh là IShardableTest, Giao diện này chứa 2 phương thức: split(int numShard)split().

Nếu hoạt động phân mảnh của bạn phụ thuộc vào số lượng mảnh được yêu cầu, bạn nên triển khai split(int numShard). Nếu không, hãy triển khai split().

Khi một lệnh kiểm thử TF được thực thi với các tham số phân mảnh --shard-count--shard-index, TF sẽ lặp lại tất cả IRemoteTest để tìm những lệnh triển khai IShardableTest. Nếu tìm thấy, lệnh này sẽ gọi split để nhận đối tượng IRemoteTest mới nhằm chạy một nhóm con các trường hợp kiểm thử cho một mảnh cụ thể.

Tôi cần biết những gì về việc triển khai phân mảnh?

  • Trình chạy của bạn chỉ có thể phân mảnh theo một số điều kiện; trong trường hợp đó, hãy trả về null khi bạn không phân mảnh.
  • Cố gắng phân mảnh càng nhiều càng tốt: chia trình chạy thành đơn vị thực thi phù hợp với trình chạy đó. Điều này thực sự phụ thuộc vào trình chạy của bạn. Ví dụ: HostTest được phân mảnh ở cấp Lớp, mỗi lớp kiểm thử được đặt trong một mảnh riêng biệt.
  • Nếu phù hợp, hãy thêm một số tuỳ chọn để kiểm soát hoạt động phân mảnh một chút. Ví dụ: AndroidJUnitTestajur-max-shard để chỉ định số lượng mảnh tối đa mà nó có thể phân mảnh, bất kể số lượng được yêu cầu.

Triển khai mẫu chi tiết

Dưới đây là một đoạn mã mẫu triển khai IShardableTest mà bạn có thể tham khảo. Bạn có thể xem toàn bộ mã tại (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android17-release/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)

/**
 * Runs all instrumentation found on current device.
 */
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
        implements IDeviceTest, IResumableTest, IShardableTest {
    ...

    /** {@inheritDoc} */
    @Override
    public Collection<IRemoteTest> split(int shardCountHint) {
        if (shardCountHint > 1) {
            Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
            for (int index = 0; index < shardCountHint; index++) {
                shards.add(getTestShard(shardCountHint, index));
            }
            return shards;
        }
        // Nothing to shard
        return null;
    }

    private IRemoteTest getTestShard(int shardCount, int shardIndex) {
        InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
        try {
            OptionCopier.copyOptions(this, shard);
        } catch (ConfigurationException e) {
            CLog.e("failed to copy instrumentation options: %s", e.getMessage());
        }
        shard.mShardIndex = shardIndex;
        shard.mTotalShards = shardCount;
        return shard;
    }
    ...
}

Ví dụ này chỉ tạo một thực thể mới của chính nó và đặt các tham số phân mảnh cho thực thể đó. Tuy nhiên, logic phân tách có thể hoàn toàn khác nhau giữa các kiểm thử; và miễn là logic đó mang tính xác định và tạo ra các nhóm con đầy đủ, thì logic đó vẫn phù hợp.

Tính độc lập

Các mảnh cần độc lập! Hai mảnh do quá trình triển khai split trong trình chạy của bạn tạo ra không được phụ thuộc vào nhau hoặc chia sẻ tài nguyên.

Hoạt động phân tách mảnh cần mang tính xác định! Đây cũng là điều bắt buộc, với cùng một điều kiện, phương thức split của bạn phải luôn trả về chính xác danh sách mảnh giống nhau theo cùng một thứ tự.

LƯU Ý: Vì mỗi mảnh có thể chạy trên các thực thể TF khác nhau, nên bạn cần đảm bảo logic split tạo ra các nhóm con loại trừ lẫn nhau và đầy đủ theo cách mang tính xác định.

Phân mảnh kiểm thử cục bộ

Để phân mảnh một kiểm thử trên TF cục bộ, bạn chỉ cần thêm tuỳ chọn --shard-count vào dòng lệnh.

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

Sau đó, TF sẽ tự động tạo lệnh cho từng mảnh và chạy các lệnh đó.

tf >l i
Command Id  Exec Time  Device          State
3           0m:03      [null-device-2]  running stub on build 0 (shard 1 of 3)
3           0m:03      [null-device-1]  running stub on build 0 (shard 0 of 3)
3           0m:03      [null-device-3]  running stub on build 0 (shard 2 of 3)

Tổng hợp kết quả kiểm thử

Vì TF không tổng hợp kết quả kiểm thử cho các lệnh gọi được phân mảnh, nên bạn cần đảm bảo dịch vụ báo cáo của mình hỗ trợ tính năng này.