Thử nghiệm liên kết

Đây là nội dung giới thiệu ngắn gọn về liên kết kiểm thử và nội dung giải thích về cách dễ dàng 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

Liên kết 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 các quy tắc kiểm thử trước và sau khi gửi ngay trong cây nguồn Android, đồng thời để lại các quyết định về nhánh và thiết bị được kiểm thử cho chính cơ sở hạ tầng kiểm thử. Định nghĩa ánh xạ kiểm thử là các tệp JSON có tên TEST_MAPPING có thể được đặt trong bất kỳ thư mục nguồn nào.

Atest có thể sử dụng các tệp TEST_MAPPING để chạy các bài kiểm thử trước khi gửi trong các thư mục liên kết. Với liên kết kiểm thử, bạn có thể thêm cùng một tập hợp kiểm thử để gửi lại các bước kiểm tra bằng một thay đổi đơn giản bên trong cây nguồn Android.

Xem các ví dụ sau:

Thêm bài kiểm thử trước khi gửi vào TEST_MAPPING cho services.core

Thêm bài kiểm thử trước khi gửi vào TEST_MAPPING cho tools/dexter sử dụng lệnh nhập

Quá trình liên kết kiểm thử dựa vào Khai thác kiểm thử Liên kết thương mại (TF) để thực thi kiểm thử 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ử của nhóm liên kết thông qua một nhóm kiểm thử. Tên của nhóm kiểm thử có thể là bất kỳ chuỗi nào. Ví dụ: Bạn có thể dùng tính năng gửi lại cho một nhóm các thử nghiệm trong quá trình xác thực các thay đổi. Bạn có thể sử dụng quy trình kiểm thử postsubmit để xác thự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 kiểm thử Liên kết thương mại chạy các mô-đun kiểm thử của ánh xạ kiểm thử cho một bản dựng nhất định, các mô-đun này phải đặt test_suites cho Soong hoặc LOCAL_COMPATIBILITY_SUITE được đặt cho Make thành một trong hai bộ sau:

  • kiểm thử chung – những kiểm thử không phụ thuộc vào chức năng dành riêng cho thiết bị (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ó). Hầu hết các bài kiểm thử đều phải nằm trong bộ kiểm thử chung, ngay cả khi chúng dành riêng cho một ABI, độ bit hoặc các tính năng phần cứng như HWASan (có một mục tiêu test_suites riêng cho mỗi ABI) và ngay cả khi chúng phải chạy trên một thiết bị.
  • device-tests (kiểm thử thiết bị) – các kiểm thử phụ thuộc vào chức năng cụ thể của thiết bị. Thông thường, bạn sẽ tìm thấy các chương trình kiểm thử này trong vendor/. Vì "dành riêng cho thiết bị" không đề cập đến chức năng ABI hoặc SoC mà các thiết bị khác có thể có hoặc không có, mà chỉ áp dụng cho chức năng dành riêng cho thiết bị a, nên điều này áp dụng cho các kiểm thử JUnit từng bit như kiểm thử gốc GTest (thường là general-tests ngay cả khi chú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 tệp tạm thời được tạo trong quá trình kiểm thử.
  • thay đổi chế độ cài đặt hệ thống về giá trị mặc định hoặc giá trị ban đầu.
  • không nên giả định một thiết bị ở một trạng thái nhất định, ví dụ: đã sẵn sàng cho chế độ gốc. Hầu hết các hoạt động kiểm thử đều không yêu cầu đặc quyền gốc để chạy. Nếu một kiểm thử phải yêu cầu thư mục gốc, thì kiểm thử phải chỉ định điều đó bằng 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ử, bạn chỉ cần thêm tệp JSON TEST_MAPPING giống như ví dụ bên dưới. Các quy tắc này sẽ đảm bảo quá trình kiểm thử chạy trong các đợt 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 nào của thư mục.

Làm theo một ví dụ

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

{
  "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": "CtsWindowManagerDeviceTestCases"
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Đặt thuộc tính

Trong ví dụ trên, presubmitpostsubmit là tên của từng nhóm kiểm thử. Hãy xem phần Xác định nhóm kiểm thử để biết thêm thông tin về nhóm kiểm thử.

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

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

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 để so khớp đường dẫn tương đối của tệp mã nguồn bất kỳ (tương ứng với thư mục chứa tệp TEST_MAPPING). Trong ví dụ trên, chương trình kiểm thử CtsWindowManagerDeviceTestCases sẽ chỉ chạy trong quá trình gửi trước khi bất kỳ tệp java nào bắt đầu bằng Cửa sổ hoặc Hoạt động (tồn tại trong cùng một thư mục của tệp TEST_MAPPING hoặc bất kỳ thư mục con nào của tệp đó) được thay đổi. Dấu gạch chéo ngược \ cần có ký tự thoát vì chúng nằm trong tệp JSON.

Thuộc tính nhập 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 cần sao chép nội dung. Lưu ý rằng các tệp TEST_MAPPING trong thư mục mẹ của đường dẫn đã nhập cũng sẽ được đưa vào. Hoạt động ánh xạ kiểm thử cho phép các lệnh nhập lồng nhau; tức là 2 tệp TEST_MAPPING có thể nhập lẫn nhau và hoạt động ánh xạ kiểm thử có thể hợp nhất đúng cách các bài kiểm thử đi kèm.

Thuộc tính options chứa các tùy chọn dòng lệnh TradeFed 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

Hãy tham khảo bài viết Xử lý quyền chọn mua qua TradeFed để biết thêm thông tin 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 bài kiểm thử gửi trước được định cấu hình trong các tệp TEST_MAPPING của thư mục hiện tại và các thư mục mẹ của thư mục đó sẽ được chạy. Atest sẽ tìm và chạy hai bài kiểm thử để 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 các tệp TEST_MAPPING trong thư mục đang làm việc (CWD) và thư mục mẹ. Atest sẽ tìm và sử dụng tệp TEST_MAPPING trong CWD và tất cả các thư mục mẹ của tệp này.

Mã nguồn cấu trúc

Ví dụ sau cho thấy cách định cấu hình 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 mục tiêu để chạy kiểm thử trong các tệp TEST_MAPPING trong thư mục đó. Lệnh sau đây sẽ 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 để 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ủ 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 kiểm thử, những kiểm thử yêu cầu thiết bị và những kiểm thử chạy trên máy chủ lưu trữ và không yêu cầu thiết bị. Các bài kiểm thử sẽ được chạy trong 2 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ả các thử nghiệm postsubmit liên quan đến các tệp trong thư mục src/project_1, chỉ chứa một hoạt động kiểm thử (C).

Hoặc bạn có thể dùng :all để chạy tất cả các lượt kiểm thử bất kể thuộc nhóm nào. Lệnh sau đây chạy 4 lượt 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 sẽ chỉ chạy các kiểm thử gửi trước được định cấu hình trong tệp TEST_MAPPING trong CWD (hoặc thư mục có sẵn) và các thư mục mẹ. Nếu bạn muốn chạy kiểm thử trong mọi tệp TEST_MAPPING trong thư mục con, hãy sử dụng tuỳ chọn --include-subdir để buộc Atest cũng đưa các lượt kiểm thử đó vào.

atest --include-subdir

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

Nhận xét ở cấp dòng được hỗ trợ

Bạn có thể thêm nhận xét ở định dạng // ở cấp dòng để bổ sung nội dung cho tệp TEST_MAPPING với nội dung mô tả về chế độ cài đặt như sau. ATest và Trade Federation sẽ xử lý trước TEST_MAPPING sang định dạng JSON hợp lệ mà không cần nhận xét. Để giữ cho tệp JSON gọn gàng và dễ đọc, chỉ ghi chú định dạng // ở cấp dòng mới được hỗ trợ.

Ví dụ:

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