Ví dụ về kiểm tra tự thiết bị

Khi một thử nghiệm thiết bị đo lường được bắt đầu, gói mục tiêu của nó sẽ được khởi động lại với mã thiết bị đo lường được đưa vào và bắt đầu thực thi. Một ngoại lệ là gói mục tiêu ở đây không thể là chính khung ứng dụng Android, chẳng hạn như gói android , vì làm như vậy sẽ dẫn đến tình huống nghịch lý là khung Android sẽ cần phải được khởi động lại, vốn hỗ trợ các chức năng của hệ thống, bao gồm bản thân thiết bị đó.

Điều này có nghĩa là quá trình kiểm thử thiết bị không thể tự đưa chính nó vào khung Android, hay còn gọi là máy chủ hệ thống, để thực thi. Để kiểm tra khung Android, mã kiểm tra chỉ có thể gọi các giao diện API công khai hoặc các giao diện được hiển thị bằng Ngôn ngữ định nghĩa giao diện Android AIDL có sẵn trong cây nguồn nền tảng. Đối với loại thử nghiệm này, việc nhắm mục tiêu bất kỳ gói cụ thể nào là không có ý nghĩa. Do đó, theo thông lệ, các công cụ như vậy sẽ được khai báo để nhắm mục tiêu gói ứng dụng thử nghiệm của chính nó, như được xác định trong thẻ <manifest> của chính nó trên AndroidManifest.xml .

Tùy thuộc vào yêu cầu, các gói ứng dụng thử nghiệm trong danh mục này cũng có thể:

  • Gói các hoạt động cần thiết để thử nghiệm.
  • Chia sẻ ID người dùng với hệ thống.
  • Được ký bằng khóa nền tảng.
  • Được biên dịch dựa trên nguồn khung chứ không phải SDK công khai.

Loại thử nghiệm thiết bị này đôi khi được gọi là tự thiết bị. Dưới đây là một số ví dụ về các thử nghiệm tự thiết bị trong nguồn nền tảng:

Ví dụ được đề cập ở đây là viết một bài kiểm thử thiết bị đo đạc mới với gói mục tiêu được đặt ở gói ứng dụng kiểm thử riêng của nó. Hướng dẫn này sử dụng bài kiểm tra sau để làm ví dụ:

Bạn nên duyệt qua mã trước để có ấn tượng sơ bộ trước khi tiếp tục.

Quyết định vị trí nguồn

Thông thường, nhóm của bạn sẽ có sẵn một mẫu địa điểm để kiểm tra mã và các địa điểm để thêm bài kiểm tra. Hầu hết các nhóm đều sở hữu một kho lưu trữ git duy nhất hoặc chia sẻ một kho lưu trữ với các nhóm khác nhưng có một thư mục con chuyên dụng chứa mã nguồn thành phần.

Giả sử vị trí gốc cho nguồn thành phần của bạn là ở <component source root> , hầu hết các thành phần đều có các thư mục srctests bên dưới nó, cùng một số tệp bổ sung như Android.mk (hoặc được chia thành các tệp .mk bổ sung), tệp kê khai AndroidManifest.xml và tệp cấu hình thử nghiệm 'AndroidTest.xml'.

Vì bạn đang thêm một thử nghiệm hoàn toàn mới, nên có thể bạn sẽ cần tạo thư mục tests bên cạnh thành phần src và điền nội dung vào đó.

Trong một số trường hợp, nhóm của bạn có thể có thêm cấu trúc thư mục đang được tests do cần phải đóng gói các bộ thử nghiệm khác nhau vào các gói ứng dụng riêng lẻ. Và trong trường hợp này, bạn sẽ cần tạo một thư mục con mới trong phần tests .

Bất kể cấu trúc như thế nào, cuối cùng bạn sẽ điền vào thư mục tests hoặc thư mục con mới được tạo với các tệp tương tự như nội dung trong thư mục instrumentation trong thay đổi gerrit mẫu. Chi tiết của từng tệp sẽ được giải thích sau trong tài liệu này.

Tệp kê khai

Giống như một dự án ứng dụng, mỗi mô-đun kiểm thử thiết bị đo đạc yêu cầu một tệp kê khai có tên AndroidManifest.xml . Để tự động bao gồm tệp này bằng tệp tạo lõi BUILD_PACKAGE , hãy cung cấp tệp này bên cạnh tệp Android.mk cho mô-đun thử nghiệm của bạn.

Nếu bạn không quen với tệp AndroidManifest.xml , hãy tham khảo Tổng quan về tệp kê khai ứng dụng

Sau đây là tệp AndroidManifest.xml mẫu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:sharedUserId="android.uid.system"
  package="android.test.example.helloworld" >

    <application>
       <uses-library android:name="android.test.runner"/>
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Một số nhận xét chọn lọc trên tệp kê khai:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

Thuộc tính package là tên gói ứng dụng: đây là mã định danh duy nhất mà khung ứng dụng Android sử dụng để xác định một ứng dụng (hoặc trong ngữ cảnh này: ứng dụng thử nghiệm của bạn). Mỗi người dùng trong hệ thống chỉ được cài đặt một ứng dụng có tên gói đó.

Hơn nữa, thuộc tính package này giống với thuộc tính mà ComponentName#getPackageName() trả về và cũng giống như thuộc tính bạn sẽ sử dụng để tương tác với các lệnh phụ pm khác nhau bằng cách sử dụng adb shell .

Lưu ý rằng mặc dù tên gói thường có cùng kiểu với tên gói Java nhưng thực tế nó có rất ít điều liên quan đến nó. Nói cách khác, gói ứng dụng (hoặc thử nghiệm) của bạn có thể chứa các lớp có bất kỳ tên gói nào, mặc dù mặt khác, bạn có thể chọn sự đơn giản và có tên gói Java cấp cao nhất trong ứng dụng hoặc thử nghiệm của mình giống hệt với tên gói ứng dụng.

android:sharedUserId="android.uid.system"

Điều này tuyên bố rằng tại thời điểm cài đặt, tệp APK này phải được cấp cùng một ID người dùng, tức là danh tính thời gian chạy, làm nền tảng cốt lõi. Lưu ý rằng điều này phụ thuộc vào gói ứng dụng được ký bằng cùng chứng chỉ với nền tảng cốt lõi (xem LOCAL_CERTIFICATE trong phần trước), tuy nhiên chúng là các khái niệm khác nhau:

  • một số quyền hoặc API được bảo vệ bằng chữ ký, yêu cầu cùng chứng chỉ ký
  • một số quyền hoặc API yêu cầu danh tính người dùng system của người gọi, yêu cầu gói gọi điện phải chia sẻ ID người dùng với system , nếu đó là gói riêng biệt với chính nền tảng cốt lõi
<uses-library android:name="android.test.runner" />

Điều này là bắt buộc đối với tất cả các thử nghiệm Thiết bị vì các lớp liên quan được đóng gói trong một tệp thư viện JAR khung riêng biệt, do đó yêu cầu các mục nhập đường dẫn lớp bổ sung khi khung ứng dụng gọi gói thử nghiệm.

android:targetPackage="android.test.example.helloworld"

Bạn có thể nhận thấy rằng targetPackage ở đây được khai báo giống với thuộc package được khai báo trong thẻ kê manifest của tệp này. Như đã đề cập trong phần kiểm thử cơ bản , danh mục kiểm thử thiết bị này thường nhằm mục đích kiểm thử các API khung, do đó, việc chúng có gói ứng dụng được nhắm mục tiêu cụ thể, ngoài chính gói ứng dụng đó là không có ý nghĩa lắm.

Tập tin cấu hình đơn giản

Mỗi mô-đun thử nghiệm mới phải có tệp cấu hình để điều khiển hệ thống xây dựng bằng siêu dữ liệu mô-đun, các phần phụ thuộc tại thời điểm biên dịch và hướng dẫn đóng gói. Trong hầu hết các trường hợp, tùy chọn tệp Blueprint dựa trên Soong là đủ. Để biết chi tiết, xem Cấu hình thử nghiệm đơn giản .

Tệp cấu hình phức tạp

Đối với những trường hợp phức tạp hơn này, bạn cũng cần viết tệp cấu hình thử nghiệm cho khai thác thử nghiệm của Android, Trade Union .

Cấu hình thử nghiệm có thể chỉ định các tùy chọn thiết lập thiết bị đặc biệt và các đối số mặc định để cung cấp cho lớp thử nghiệm. Xem ví dụ tại /platform_testing/tests/example/instrumentation/AndroidTest.xml .

Một ảnh chụp nhanh được bao gồm ở đây để thuận tiện:

<configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>

Một số nhận xét chọn lọc trên file cấu hình thử nghiệm:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>

Điều này yêu cầu Liên đoàn Thương mại cài đặt HelloWorldTests.apk vào thiết bị mục tiêu bằng cách sử dụng target_preparer được chỉ định. Có nhiều công cụ chuẩn bị mục tiêu dành cho các nhà phát triển trong Liên đoàn Thương mại và những công cụ này có thể được sử dụng để đảm bảo thiết bị được thiết lập đúng cách trước khi thực hiện thử nghiệm.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

Điều này chỉ định lớp kiểm thử của Liên đoàn Thương mại sẽ sử dụng để thực hiện kiểm thử và chuyển gói trên thiết bị sẽ được thực thi và khung chạy kiểm thử là JUnit trong trường hợp này.

Để biết thêm thông tin, hãy xem Cấu hình mô-đun thử nghiệm .

Tính năng JUnit4

Việc sử dụng thư viện android-support-test làm trình chạy thử cho phép áp dụng các lớp kiểm tra kiểu JUnit4 mới và thay đổi gerrit mẫu chứa một số cách sử dụng rất cơ bản các tính năng của nó. Xem ví dụ tại /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java .

Mặc dù các mẫu thử nghiệm thường dành riêng cho các nhóm thành phần, nhưng có một số mẫu sử dụng thường hữu ích.

@RunWith(JUnit4.class)
public class HelloWorldTest {

Một sự khác biệt đáng kể trong JUnit4 là các bài kiểm tra không còn cần thiết phải kế thừa từ một lớp kiểm tra cơ sở chung nữa; thay vào đó, bạn viết các bài kiểm tra trong các lớp Java đơn giản và sử dụng chú thích để chỉ ra các ràng buộc và thiết lập kiểm tra nhất định. Trong ví dụ này, chúng tôi hướng dẫn rằng lớp này nên được chạy dưới dạng thử nghiệm JUnit4.

    @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...

Các chú thích @Before@After được JUnit4 sử dụng trên các phương thức để thực hiện thiết lập thử nghiệm trước và phân tích sau thử nghiệm. Tương tự, các chú thích @BeforeClass@AfterClass được JUnit4 sử dụng trên các phương thức để thực hiện thiết lập trước khi thực hiện tất cả các thử nghiệm trong một lớp thử nghiệm và phân tích sau đó. Lưu ý rằng các phương thức thiết lập và phân chia phạm vi lớp phải ở trạng thái tĩnh. Đối với các phương thức thử nghiệm, không giống như phiên bản JUnit trước đó, chúng không còn cần bắt đầu tên phương thức bằng test , thay vào đó, mỗi phương thức phải được chú thích bằng @Test . Như thường lệ, các phương thức thử nghiệm phải công khai, không khai báo giá trị trả về, không nhận tham số và có thể đưa ra ngoại lệ.

Truy cập lớp thiết bị

Mặc dù không được đề cập trong ví dụ hello world cơ bản, nhưng việc kiểm thử Android yêu cầu quyền truy cập vào phiên bản Instrumentation khá phổ biến: đây là giao diện API cốt lõi cung cấp quyền truy cập vào ngữ cảnh ứng dụng, các API kiểm tra liên quan đến vòng đời hoạt động và hơn thế nữa.

Vì các thử nghiệm JUnit4 không còn yêu cầu một lớp cơ sở chung nên không cần thiết phải lấy phiên bản Instrumentation thông qua InstrumentationTestCase#getInstrumentation() nữa, thay vào đó, trình chạy thử nghiệm mới sẽ quản lý nó thông qua InstrumentationRegistry , nơi lưu trữ thiết lập theo ngữ cảnh và môi trường do khung công cụ tạo ra.

Để truy cập phiên bản của lớp Instrumentation , chỉ cần gọi phương thức tĩnh getInstrumentation() trên lớp InstrumentationRegistry :

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Xây dựng và thử nghiệm tại địa phương

Đối với các trường hợp sử dụng phổ biến nhất, hãy sử dụng Atest .

Đối với các trường hợp phức tạp hơn yêu cầu tùy chỉnh nhiều hơn, hãy làm theo hướng dẫn về thiết bị đo đạc .