Thử nghiệm liên kết

Đây là phần giới thiệu ngắn gọn về việc liên kết kiểm thử và giải thích cách 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 khi gửi và sau khi gửi trực tiếp trong cây nguồn Android, đồng thời để lại các quyết định về nhánh và thiết bị cần kiểm thử cho 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 mà bạn có thể đặt vào 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 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ài kiểm tra với một thay đổi tối thiểu bên trong cây nguồn Android.

Xem các ví dụ sau:

Việc liên kết kiểm thử dựa vào bộ kiểm thử Liên minh thương mại (TF) để thực thi kiểm thử và báo cáo kết quả.

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

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 một nhóm kiểm thử có thể là bất kỳ chuỗi nào. Ví dụ: presubmit có thể là tên của một nhóm kiểm thử để chạy khi xác thực các thay đổi. Ngoài ra, postsubmit có thể là các bài kiểm thử dùng để 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

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

  • general-tests dành cho các kiểm thử không phụ thuộc vào các tính 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 các thiết bị không có). Hầu hết các chương trình kiểm thử phải nằm trong bộ general-tests, ngay cả khi các chương trình kiểm thử đó dành riêng cho một ABI hoặc bitness 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 biệt cho mỗi ABI) và ngay cả khi các chương trình kiểm thử đó phải chạy trên một thiết bị.
  • device-tests dùng cho các chương trình 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, các bài kiểm thử này nằm trong vendor/. Cụ thể theo thiết bị chỉ đề cập đến các chức năng dành riêng cho một thiết bị, vì vậy, điều này áp dụng cho các kiểm thử JUnit cũng như kiểm thử GTest (thường được đánh dấu 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 kiểm thử để chạy trong một bộ kiểm thử

Để chạy bên trong một bộ kiểm thử, kiểm thử phải:

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

Đối với thư mục yêu cầu mức độ bao phủ kiểm thử, hãy thêm một tệp JSON TEST_MAPPING giống như ví dụ. Các quy tắc này đảm bảo rằng các chương trình kiểm thử chạy trong quy trình 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 hỗ trợ chú thí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": "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 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 minh thương mại (ví dụ: đường dẫn tài nguyên đến tệp XML kiểm thử, 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 kiểm thử cần chạy, hãy sử dụng các tuỳ chọn như include-filter. Xem ví dụ về cách sử dụng include-filter.

Chế độ cài đặt host của một kiểm thử cho biết liệu kiểm thử đó có phải là kiểm thử không cần 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ử, bạn 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 đặt 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 bất kỳ tệp mã nguồn nào (so với thư mục chứa tệp TEST_MAPPING). Trong ví dụ này, CtsWindowManagerDeviceTestCases kiểm thử 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 đó. Bạn cần phải thoát dấu gạch chéo ngược (\) vì chúng nằm trong tệp JSON.

Thuộc tính imports cho phép bạn đưa các chương trình kiểm thử vào các tệp TEST_MAPPING khác mà không cần sao chép nội dung. Các tệp TEST_MAPPING trong thư mục mẹ của đường dẫn đã nhập cũng được đưa vào. Tính năng ánh xạ kiểm thử cho phép nhập lồng nhau; nghĩa là hai tệp TEST_MAPPING có thể nhập lẫn nhau và tính năng ánh xạ kiểm thử có thể hợp nhất các kiểm thử được đưa vào.

Thuộc tính options chứa các tuỳ 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 phần Xử lý tuỳ chọn trong 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

Cách thực thi các quy tắc kiểm thử trước khi gửi trên máy:

  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ử trước khi gửi đượ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 chương trình kiểm thử trước khi gửi (A và B).

Đây là cách đơn giản nhất để chạy các bài kiểm thử gửi trước trong các tệp TEST_MAPPING trong thư mục đang làm việc (CWD) hiện tại và thư mục mẹ. Atest xác định 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ụ 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 mục tiêu để chạy kiểm thử trong các tệp TEST_MAPPING trong thư mục đó. Lệnh sau đây chạy hai chương trình 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ể 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 những 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 những chương trình kiểm thử được định cấu hình đối với 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 hoạt độ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ữ không yêu cầu thiết bị. Các chương trình kiểm thử đượ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 các nhóm kiểm thử trong lệnh Atest. Lệnh sau đây sẽ chạy tất cả các kiểm thử postsubmit liên quan đến các tệp trong thư mục src/project_1, thư mục này chỉ chứa một kiểm thử (C).

Hoặc bạn có thể sử dụng :all để chạy tất cả các bài kiểm thử bất kể nhóm. 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 thư mục con

Theo mặc định, việc chạy kiểm thử trong TEST_MAPPING bằng Atest chỉ chạy các kiểm thử trước khi gửi được định cấu hình trong tệp TEST_MAPPING trong CWD (hoặc thư mục đã cho) và các thư mục mẹ của tệp đó. Nếu bạn muốn chạy kiểm thử trong tất cả các tệp TEST_MAPPING trong các 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 kiểm thử A. Với tuỳ chọn --include-subdir, Atest sẽ chạy hai chương trình 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 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 xử lý trước TEST_MAPPING thành định dạng JSON hợp lệ mà không có nhận xét. Để giữ cho tệp JSON luôn sạch sẽ, chỉ hỗ trợ nhận xét định dạng // cấp dòng.

Ví dụ:

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