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

Khi viết trình chạy kiểm thử, điều quan trọng là cần nghĩ đến khả năng có thể mở rộng. Hỏi chính bạn, "nếu người chạy thử nghiệm của tôi phải chạy 200 nghìn trường hợp thử nghiệm" sẽ mất bao lâu?

Phân đoạn là một trong những câu trả lời có sẵn trong Liên đoàn Thương mại. Cần có chia nhỏ tất cả các bài kiểm thử mà trình chạy cần thành nhiều phần có thể song song.

Trang này mô tả cách làm cho trình chạy của bạn có thể phân đoạn cho Tradefeed.

Giao diện để triển khai

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

Nếu việc phân đoạn của bạn phụ thuộc vào số lượng phân đoạn đượ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 thực thi một lệnh kiểm thử TF với các tham số phân đoạn --shard-count--shard-index, TF lặp lại tất cả IRemoteTest để tìm các lỗi triển khai IShardableTest. Nếu tìm thấy, ứng dụng sẽ gọi split tới nhận đối tượng IRemoteTest mới để chạy một tập hợp con các trường hợp kiểm thử cho một đối tượng cụ thể phân đoạn.

Tôi nên biết gì về việc triển khai phần phân tách?

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

Quy trình triển khai mẫu chi tiết

Dưới đây là một đoạn mã mẫu triển khai IShardableTest, bạn có thể tham chiếu. Bạn có thể xem toàn bộ mã nguồn tại (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/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 phân đoạn các tham số vào nó. Tuy nhiên, logic phân tách có thể hoàn toàn khác với thử nghiệm để thử nghiệm; và miễn là mang tính xác định và mang lại kết quả chung là không có vấn đề gì.

Độc lập

Các phân đoạn cần phải hoạt động độc lập! Hai phân đoạn được tạo bằng cách triển khai của bạn split trong trình chạy của bạn không nên có các phần phụ thuộc lẫn nhau hoặc có chung của chúng tôi.

Việc phân tách phân đoạn cần phải có kết quả tất định! Đây cũng là điều bắt buộc, do cùng một điều kiện, phương thức split của bạn sẽ luôn trả về cùng một danh sách phân đoạn theo cùng thứ tự.

LƯU Ý: Do mỗi phân đoạn có thể chạy trên các thực thể TF khác nhau nên điều quan trọng là phải đảm bảo logic split tạo ra các tập hợp con loại trừ lẫn nhau và đầy đủ theo cách xác định.

Phân đoạn một kiểm thử cục bộ

Để phân đoạn 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 các lệnh cho từng phân đoạn 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 thực hiện bất kỳ việc tổng hợp kết quả kiểm thử nào cho các lệnh gọi được phân đoạn, nên bạn cần đảm bảo dịch vụ báo cáo của bạn hỗ trợ công cụ đó.