Khi một kiểm thử đo lường được bắt đầu, gói đích của kiểm thử đó sẽ được khởi động lại với mã đo lường được chèn và khởi tạo để thực thi. Một trường hợp ngoại lệ là gói đích ở đâ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 khởi động lại, đây là điều hỗ trợ các chức năng hệ thống, bao gồm cả chính hoạt động đo lường.
Điều này có nghĩa là một kiểm thử đo lường không thể tự chèn vào khung Android (còn gọi là máy chủ hệ thống) để thực thi. Để kiểm thử khung Android, mã kiểm thử chỉ có thể gọi các giao diện API công khai hoặc những giao diện được hiển thị bằng Ngôn ngữ định nghĩa giao diện Android AIDL có trong cây nguồn nền tảng. Đối với danh mục kiểm thử này, việc nhắm đến bất kỳ gói cụ thể nào đều không có ý nghĩa. Do đó, theo thông lệ, các hoạt động đo lường như vậy sẽ được khai báo để nhắm đến gói ứng dụng kiểm thử riêng, như được xác định trong thẻ <manifest>
riêng của AndroidManifest.xml
.
Tuỳ thuộc vào các yêu cầu, các gói ứng dụng kiểm thử trong danh mục này cũng có thể:
- Các hoạt động liên quan đến gói cần thiết cho việc kiểm thử.
- Chia sẻ mã nhận dạng người dùng với hệ thống.
- Được ký bằng khoá 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.
Danh mục kiểm thử đo lường này đôi khi được gọi là tự đo lường. Sau đây là một số ví dụ về các kiểm thử tự đo lường trong nguồn nền tảng:
Ví dụ được đề cập ở đây là viết một phép kiểm thử đo lường mới với gói mục tiêu được đặt tại gói ứng dụng kiểm thử riêng. Hướng dẫn này sử dụng thử nghiệm sau đây làm ví dụ:
Bạn nên duyệt qua mã trước để 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 các vị trí cần kiểm tra trong mã và các vị trí cần thêm kiểm thử. 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ó thư mục src
và tests
trong đó, cũng như 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 kiểm thử "AndroidTest.xml".
Vì đang thêm một kiểm thử 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 thư mục đó.
Trong một số trường hợp, nhóm của bạn có thể có thêm các cấu trúc thư mục trong tests
do cần đóng gói các bộ kiểm thử khác nhau vào từng apk riêng lẻ. Trong trường hợp này, bạn cần tạo một thư mục con mới trong tests
.
Bất kể cấu trúc nào, bạn sẽ kết thúc việc điền vào thư mục tests
hoặc thư mục con mới tạo bằng các tệp tương tự như trong thư mục instrumentation
trong thay đổi mẫu gerrit. Thông tin chi tiết về từng tệp sẽ được giải thích ở phần sau của tài liệu này.
Tệp kê khai
Tương tự như dự án ứng dụng, mỗi mô-đun kiểm thử đo lường đều yêu cầu một tệp kê khai có tên là AndroidManifest.xml
. Để tự động thêm tệp này bằng cách sử dụng tệp makefile cốt lõi BUILD_PACKAGE
, hãy cung cấp tệp này bên cạnh tệp Android.mk
cho mô-đun kiểm thử của bạn.
Nếu bạn chưa hiểu rõ về tệp AndroidManifest.xml
, hãy tham khảo phần 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 về 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à giá trị nhận dạng duy nhất mà khung ứng dụng Android dùng để nhận dạng một ứng dụng (hoặc trong ngữ cảnh này: ứng dụng kiểm thử của bạn). Mỗi người dùng trong hệ thống chỉ có thể 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 những gì ComponentName#getPackageName()
trả về, đồng thời cũng giống với những gì bạn sẽ dùng để tương tác với nhiều lệnh phụ pm
sử dụng adb shell
.
Xin 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ế thì tên gói này có rất ít điểm chung với tên gói Java. Nói cách khác, gói ứng dụng (hoặc gói kiểm thử) có thể chứa các lớp có tên gói bất kỳ, mặc dù bạn có thể chọn cách đơn giản và đặt tên gói Java cấp cao nhất trong ứng dụng hoặc kiểm thử giống với tên gói ứng dụng.
android:sharedUserId="android.uid.system"
Thẻ này khai báo rằng tại thời điểm cài đặt, tệp APK này sẽ được cấp cùng một mã nhận dạng người dùng (tức là danh tính thời gian chạy) như nền tảng cốt lõi. Xin lưu ý rằng điều này phụ thuộc vào việc apk được ký bằng cùng một chứng chỉ với nền tảng cốt lõi (xem LOCAL_CERTIFICATE
trong phần trước), nhưng đây là những 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 phải có 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 phương thức gọi, yêu cầu gói gọi chia sẻ mã nhận dạng người dùng vớisystem
, nếu đó là một 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" />
Đây là yêu cầu bắt buộc đối với tất cả các kiểm thử đo lường 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 đó, cần có thêm các mục nhập classpath khi gói kiểm thử được gọi bởi khung ứng dụng.
android:targetPackage="android.test.example.helloworld"
Có thể bạn đã nhận thấy rằng targetPackage
ở đây được khai báo giống như thuộc tính package
được khai báo trong thẻ manifest
của tệp này. Như đã đề cập trong phần kiến thức cơ bản về kiểm thử, danh mục kiểm thử đo lường này thường dành cho các API của khung kiểm thử, vì vậy, việc có một gói ứng dụng được nhắm đến cụ thể (ngoài chính nó) không có nhiều ý nghĩa.
Tệp cấu hình đơn giản
Mỗi mô-đun kiểm thử mới phải có một tệp cấu hình để hướng dẫn hệ thống bản dựng bằng siêu dữ liệu mô-đun, các phần phụ thuộc tại thời gian biên dịch và hướng dẫn đóng gói. Trong hầu hết các trường hợp, lựa chọn tệp Blueprint dựa trên Soong là đủ. Để biết thông tin chi tiết, hãy xem phần Cấu hình kiểm thử đơ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 một tệp cấu hình kiểm thử cho bộ kiểm thử của Android, Trade Federation.
Cấu hình kiểm thử có thể chỉ định các lựa 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 kiểm thử. Hãy xem ví dụ tại /platform_testing/tests/example/instrumentation/AndroidTest.xml.
Để thuận tiện, chúng tôi có chụp nhanh một phần nội dung:
<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 về tệp cấu hình kiểm thử:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
Lệnh này yêu cầu Trade Federation cài đặt HelloWorldTests.apk vào thiết bị mục tiêu bằng cách sử dụng một target_preparer được chỉ định. Có nhiều trình chuẩn bị mục tiêu mà nhà phát triển có thể sử dụng trong Trade Federation và những trình này có thể được dùng để đảm bảo thiết bị được thiết lập đúng cách trước khi thực thi kiểm thử.
<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>
Thao tác này chỉ định lớp kiểm thử Trade Federation sẽ dùng để thực thi kiểm thử và truyền gói trên thiết bị sẽ được thực thi cũng như khung trình chạy kiểm thử (trong trường hợp này là JUnit).
Để biết thêm thông tin, hãy xem phần Cấu hình mô-đun kiểm thử.
Tính năng JUnit4
Việc sử dụng thư viện android-support-test
làm trình chạy kiểm thử cho phép áp dụng các lớp kiểm thử kiểu JUnit4 mới và thay đổi mẫu gerrit chứa một số cách sử dụng rất cơ bản các tính năng của thư viện này. Xem ví dụ tại /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java.
Mặc dù các mẫu kiểm thử 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 điểm khác biệt đáng kể trong JUnit4 là các kiểm thử không còn bắt buộc phải kế thừa từ một lớp kiểm thử cơ sở chung; thay vào đó, bạn viết các kiểm thử trong các lớp Java thuần tuý và sử dụng chú thích để cho biết một số chế độ thiết lập và các ràng buộc kiểm thử. Trong ví dụ này, chúng ta đang hướng dẫn rằng lớp này sẽ chạy dưới dạng một kiểm thử JUnit4.
@BeforeClass
public static void beforeClass() {
...
@AfterClass
public static void afterClass() {
...
@Before
public void before() {
...
@After
public void after() {
...
@Test
@SmallTest
public void testHelloWorld() {
...
Chú thích @Before
và @After
được JUnit4 dùng trên các phương thức để thực hiện quá trình thiết lập trước khi kiểm thử và huỷ sau khi kiểm thử. Tương tự, các chú thích @BeforeClass
và @AfterClass
được JUnit4 dùng trên các phương thức để thực hiện quá trình thiết lập trước khi thực thi tất cả các kiểm thử trong một lớp kiểm thử và sau đó là quá trình huỷ thiết lập. Lưu ý rằng các phương thức thiết lập và huỷ bỏ phạm vi lớp phải là phương thức tĩnh. Đối với các phương thức kiểm thử, không giống như trong phiên bản JUnit trước đó, các phương thức này không còn cần phải bắt đầu tên phương thức bằng test
nữa, 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 kiểm thử phải là phương thức công khai, không khai báo giá trị trả về, không nhận tham số và có thể gửi các trường hợp ngoại lệ.
Quyền truy cập vào lớp đo lường
Mặc dù không có trong ví dụ cơ bản về Hello World, nhưng khá phổ biến khi một bài kiểm thử Android yêu cầu quyền truy cập vào phiên bản Instrumentation
: đây là giao diện API cốt lõi cung cấp quyền truy cập vào các ngữ cảnh ứng dụng, các API kiểm thử liên quan đến vòng đời hoạt động và nhiều API khác.
Vì các kiểm thử JUnit4 không còn yêu cầu một lớp cơ sở chung, nên bạn không cần phải lấy thực thể Instrumentation
thông qua InstrumentationTestCase#getInstrumentation()
nữa. Thay vào đó, trình chạy kiểm thử mới sẽ quản lý thực thể này thông qua InstrumentationRegistry
, nơi lưu trữ chế độ thiết lập theo bối cảnh và môi trường do khung đo lường tạo.
Để truy cập vào thực thể của lớp Instrumentation
, bạn 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à kiểm thử cục bộ
Đố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 những trường hợp phức tạp hơn đòi hỏi mức độ tuỳ chỉnh cao hơn, hãy làm theo hướng dẫn về việc đo lường.