Thử nghiệm liên kết

Đây là giới thiệu ngắn gọn về liên kết thử nghiệm và giải thích cách nhận bắt đầu định cấu hình kiểm thử trong Dự án nguồn mở Android (AOSP).

Giới thiệu về liên kết thử nghiệm

Lập bản đồ kiểm thử là một phương pháp dựa trên Gerrit cho phép nhà phát triển tạo và quy tắc sau khi gửi ngay trong cây nguồn Android và để các quyết định về nhánh và thiết bị để kiểm tra cơ sở hạ tầng kiểm thử. Định nghĩa liên kết kiểm thử là các tệp JSON có tên TEST_MAPPING mà bạn có thể vào bất kỳ thư mục nguồn nào.

Atest có thể dùng các tệp TEST_MAPPING để chạy các bài kiểm thử gửi trước trong thư mục liên kết. Với liên kết thử nghiệm, bạn có thể thêm cùng một nhóm thử nghiệm vào các bước kiểm tra trước khi gửi với một thay đổi nhỏ bên trong cây nguồn Android.

Xem các ví dụ sau:

Liên kết thử nghiệm dựa trên Khai thác thử nghiệm của Liên đoàn Thương mại (TF) để thử nghiệm thực thi và báo cáo kết quả.

Xác định nhóm kiểm thử

Kiểm thử các bài kiểm thử nhóm ánh xạ bằng một nhóm kiểm thử. Tên của nhóm thử nghiệm có thể là bất kỳ chuỗi nào. Ví dụ: Bạn có thể đặt tên gửi lại cho một nhóm thử nghiệm để sẽ chạy khi xác thực các thay đổi. Và postsubmit có thể là các kiểm thử dùng để xác thực các bản dựng sau khi hợp nhất các thay đổi.

Quy tắc tập lệnh tạo gói

Để khai thác thử nghiệm của Liên đoàn thương mại để chạy các mô-đun kiểm thử cho một bản dựng nhất định, những mô-đun này phải có test_suites được đặt cho bộ Soong hoặc LOCAL_COMPATIBILITY_SUITE dành cho Make to một trong hai bộ sau:

  • general-tests dành cho các thử nghiệm không phụ thuộc vào thiết bị cụ thể các khả năng (chẳng hạn như phần cứng dành riêng cho nhà cung cấp mà hầu hết thiết bị không có có). Hầu hết các kiểm thử đều phải nằm trong bộ công cụ general-tests, ngay cả khi chúng là dành riêng cho một ABI, bit bit hoặc tính năng phần cứng như HWASan (có mục tiêu test_suites riêng biệt cho mỗi ABI) và ngay cả khi chúng phải chạy trên một thiết bị.
  • device-tests dành cho các kiểm thử phụ thuộc vào các chức năng dành riêng cho thiết bị. Thông thường, bạn có thể tìm thấy các chương trình kiểm thử này trong vendor/. Dành riêng cho từng thiết bị chỉ đề cập đến những tính năng dành riêng cho một thiết bị, nên điều này áp dụng cho thử nghiệm JUnit cũng như thử nghiệm GTest (thường được đánh dấu là general-tests ngay cả khi các ứng dụng đó dành riêng cho ABI).

Ví dụ:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

Định cấu hình các bài kiểm thử để chạy trong một bộ kiểm thử

Để một chương trình kiểm thử chạy bên trong một bộ kiểm thử, quy trình kiểm thử:

  • Không được có bất kỳ nhà cung cấp bản dựng nào.
  • Phải dọn dẹp sau khi hoàn tất, chẳng hạn như bằng cách xoá mọi các tệp được tạo trong quá trình kiểm thử.
  • Phải thay đổi chế độ cài đặt hệ thống về giá trị mặc định hoặc giá trị gốc.
  • Không nên giả định rằng thiết bị đang ở một trạng thái nhất định, ví dụ: đã sẵn sàng cho thư mục gốc. Hầu hết các chương trình kiểm thử đều không yêu cầu đặc quyền gốc để chạy. Nếu một bài kiểm thử phải yêu cầu gốc, nó phải chỉ định rằng với RootTargetPreparer trong AndroidTest.xml, như trong ví dụ sau:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

Tạo tệp ánh xạ thử nghiệm

Đối với thư mục cần phạm vi kiểm thử, hãy thêm tệp JSON TEST_MAPPING tương tự như ví dụ. Những quy tắc này đảm bảo rằng các thử nghiệm sẽ chạy trong kiểm tra trước khi gửi khi có bất kỳ tệp nào được chạm vào trong thư mục đó hoặc bất kỳ thư mục con.

Làm theo một ví dụ

Dưới đây là tệp TEST_MAPPING mẫu (ở định dạng JSON nhưng có nhận xét được hỗ trợ):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Đặt thuộc tính

Trong ví dụ, presubmitpostsubmit là tên của mỗi biến nhóm thử nghiệm. Xem bài viết Xác định nhóm thử nghiệm để biết thêm thông tin về nhóm thử nghiệm.

Bạn có thể đặt tên cho mô-đun kiểm thử hoặc bài kiểm thử tích hợp Liên đoàn Thương mại name (đường dẫn tài nguyên đến tệp XML thử nghiệm, ví dụ: uiautomator/uiautomator-demo) trong giá trị của thuộc tính name. Xin lưu ý rằng trường name không thể sử dụng lớp name hoặc phương thức kiểm thử name. Để thu hẹp thử nghiệm để chạy, sử dụng các tuỳ chọn như include-filter. Xem (sử dụng mẫu include-filter).

Chế độ cài đặt host của quy trình kiểm thử cho biết liệu kiểm thử có phải là kiểm thử không có thiết bị hay không có chạy trên máy chủ hay không. Giá trị mặc định là false, nghĩa là bài kiểm thử cần có một thiết bị để chạy. Sau đây là các loại kiểm thử được hỗ trợ HostGTest cho Tệp nhị phân GTest và HostTest cho JUnit kiểm thử.

Thuộc tính file_patterns cho phép bạn thiết lập danh sách các chuỗi biểu thức chính quy để khớp đường dẫn tương đối của mọi tệp mã nguồn (tương đối so với thư mục chứa tệp TEST_MAPPING). Trong ví dụ, kiểm thử CtsWindowManagerDeviceTestCases chỉ chạy trong phần gửi trước khi tệp Java bắt đầu bằng Window hoặc Activity, tồn tại trong cùng thư mục với Tệp TEST_MAPPING hoặc bất kỳ thư mục con nào của tệp này đã bị thay đổi. Dấu gạch chéo ngược `` cần được thoát vì chúng nằm trong tệp JSON.

Thuộc tính imports cho phép bạn đưa các bài kiểm thử vào các tệp TEST_MAPPING khác mà không sao chép nội dung. Các tệp TEST_MAPPING trong tệp mẹ Các thư mục của đường dẫn đã nhập cũng được bao gồm. Liên kết kiểm thử cho phép các lệnh nhập lồng nhau; điều này có nghĩa là 2 tệp TEST_MAPPING có thể nhập lẫn nhau và liên kết thử nghiệm có thể hợp nhất các thử nghiệm đi kèm.

Thuộc tính options chứa các tuỳ chọn dòng lệnh Tradefeed bổ sung.

Để xem danh sách đầy đủ các tuỳ chọn có sẵn cho một kiểm thử nhất định, hãy chạy:

tradefed.sh run commandAndExit [test_module] --help

Tham khảo Xử lý quyền chọn trong Tradefeed để biết thêm chi tiết về cách hoạt động của các tuỳ chọn.

Chạy kiểm thử bằng Atest

Để thực thi cục bộ quy tắc kiểm thử trước khi gửi:

  1. Chuyển đến thư mục chứa tệp TEST_MAPPING.
  2. Chạy lệnh:

    atest
    

Tất cả các thử nghiệm gửi trước được định cấu hình trong các tệp TEST_MAPPING của và các thư mục mẹ của thư mục đó sẽ được chạy. Atest định vị và chạy hai chương trình kiểm thử đối với yêu cầu gửi trước (A và B).

Đây là cách đơn giản nhất để chạy bài kiểm thử trước khi gửi trong TEST_MAPPING trong thư mục đang làm việc (CWD) và thư mục mẹ. Atest tìm và sử dụng tệp TEST_MAPPING trong CWD và tất cả tệp mẹ của nó .

Mã nguồn cấu trúc

Ví dụ này cho thấy cách bạn có thể định cấu hình các tệp TEST_MAPPING trên cây nguồn:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

Nội dung của src/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

Nội dung của src/project_1/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

Nội dung của src/project_2/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

Chỉ định thư mục đích

Bạn có thể chỉ định một thư mục đích để chạy kiểm thử trong các tệp TEST_MAPPING trong đó thư mục. Lệnh sau đây chạy hai kiểm thử (A, B):

atest --test-mapping src/project_1

Chạy quy tắc kiểm thử sau khi gửi

Bạn cũng có thể sử dụng lệnh này để chạy các quy tắc kiểm thử sau khi gửi được xác định trong TEST_MAPPING trong src_path (mặc định là CWD) và các thư mục mẹ của nó:

atest [--test-mapping] [src_path]:postsubmit

Chỉ chạy các chương trình kiểm thử không cần thiết bị

Bạn có thể sử dụng tuỳ chọn --host cho Atest để chỉ chạy các chương trình kiểm thử được định cấu hình dựa trên máy chủ lưu trữ không yêu cầu thiết bị. Nếu không có tuỳ chọn này, Atest sẽ chạy cả hai phép kiểm thử, những ứng dụng cần thiết bị và hệ thống chạy trên máy chủ và không cần thiết bị. Chiến lược phát hành đĩa đơn thử nghiệm được chạy trong hai bộ riêng biệt:

atest [--test-mapping] --host

Xác định nhóm thử nghiệm

Bạn có thể chỉ định nhóm kiểm thử trong lệnh Atest. Lệnh sau đây sẽ chạy tất cả hoạt động kiểm thử postsubmit liên quan đến tệp trong thư mục src/project_1 chỉ chứa một phép kiểm thử (C).

Hoặc bạn có thể sử dụng :all để chạy mọi kiểm thử bất kể nhóm. Nội dung sau đây chạy bốn kiểm thử (A, B, C, X):

atest --test-mapping src/project_1:all

Bao gồm các thư mục con

Theo mặc định, việc chạy các chương trình kiểm thử trong TEST_MAPPING bằng Atest chỉ chạy trước khi gửi các kiểm thử được định cấu hình trong tệp TEST_MAPPING trong CWD (hoặc thư mục nhất định) và các thư mục mẹ của thư mục đó. Nếu bạn muốn chạy thử nghiệm ở tất cả TEST_MAPPING tệp trong thư mục con, hãy dùng tuỳ chọn --include-subdir để buộc Atest cũng đưa các kiểm thử đó vào.

atest --include-subdir

Nếu không có tuỳ chọn --include-subdir, Atest chỉ chạy chương trình kiểm thử A. Với --include-subdir, Atest chạy hai kiểm thử (A, B).

Hỗ trợ nhận xét ở cấp dòng

Bạn có thể thêm nhận xét ở định dạng // ở cấp dòng để bổ sung chi tiết cho TEST_MAPPING chứa nội dung mô tả về chế độ cài đặt như sau. ATest và Liên đoàn Thương mại xử lý trước TEST_MAPPING sang định dạng JSON hợp lệ mà không cần nhận xét. Để giữ lại tệp JSON đã sạch, chỉ có nhận xét về định dạng // ở cấp dòng được hỗ trợ.

Ví dụ:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}