계측 테스트가 시작되면 계측 코드가 삽입되고 실행을 위해 시작된 대상 패키지가 다시 시작됩니다. 한 가지 예외는 여기에서 대상 패키지가 Android 애플리케이션 프레임워크 자체(예: android
패키지)일 수 없다는 것입니다. 그렇게 하면 Android 프레임워크를 다시 시작해야 하는 역설적인 상황이 발생할 수 있기 때문입니다. 이는 계측을 포함하여 시스템 기능을 지원하는 것입니다. 그 자체.
즉, 계측 테스트는 실행을 위해 시스템 서버라고도 하는 Android 프레임워크에 자체를 삽입할 수 없습니다. Android 프레임워크를 테스트하기 위해 테스트 코드는 공개 API 표면 또는 플랫폼 소스 트리에서 사용 가능한 Android 인터페이스 정의 언어 AIDL 을 통해 노출된 표면만 호출할 수 있습니다. 이 테스트 범주의 경우 특정 패키지를 대상으로 하는 것은 의미가 없습니다. 따라서 이러한 계측은 AndroidManifest.xml
의 자체 <manifest>
태그에 정의된 대로 자체 테스트 애플리케이션 패키지를 대상으로 선언하는 것이 일반적입니다.
요구 사항에 따라 이 범주의 테스트 응용 프로그램 패키지는 다음과 같을 수도 있습니다.
- 테스트에 필요한 번들 활동.
- 사용자 ID를 시스템과 공유하십시오.
- 플랫폼 키로 서명해야 합니다.
- 공개 SDK가 아닌 프레임워크 소스에 대해 컴파일되어야 합니다.
이러한 계측 테스트 범주를 자체 계측이라고도 합니다. 다음은 플랫폼 소스에서 자체 계측 테스트의 몇 가지 예입니다.
여기에서 다루는 예제는 자체 테스트 애플리케이션 패키지에 설정된 대상 패키지로 새로운 계측 테스트를 작성하는 것입니다. 이 가이드에서는 다음 테스트를 예로 사용합니다.
진행하기 전에 대략적인 인상을 얻기 위해 먼저 코드를 탐색하는 것이 좋습니다.
소스 위치 결정
일반적으로 팀에는 코드를 체크인할 위치와 테스트를 추가할 위치에 대한 패턴이 이미 정해져 있습니다. 대부분의 팀은 단일 git 리포지토리를 소유하거나 다른 팀과 공유하지만 구성 요소 소스 코드가 포함된 전용 하위 디렉터리가 있습니다.
구성 요소 소스의 루트 위치가 <component source root>
에 있다고 가정하면 대부분의 구성 요소에는 그 아래에 src
및 tests
폴더가 있고 Android.mk
(또는 추가 .mk
파일로 분할), 매니페스트 파일 AndroidManifest.xml
와 같은 일부 추가 파일이 있습니다. AndroidManifest.xml
및 테스트 구성 파일 'AndroidTest.xml'.
완전히 새로운 테스트를 추가하고 있으므로 아마도 구성 요소 src
옆에 tests
디렉토리를 만들고 콘텐츠로 채워야 할 것입니다.
경우에 따라 여러 테스트 모음을 개별 apk로 패키징해야 하기 때문에 팀에서 tests
중인 추가 디렉터리 구조가 있을 수 있습니다. 이 경우 tests
아래에 새 하위 디렉토리를 만들어야 합니다.
구조에 관계없이 샘플 gerrit 변경의 instrumentation
디렉토리에 있는 것과 유사한 파일로 tests
디렉토리 또는 새로 생성된 하위 디렉토리를 채우게 됩니다. 아래 섹션에서 각 파일에 대해 자세히 설명합니다.
매니페스트 파일
일반 애플리케이션과 마찬가지로 각 계측 테스트 모듈에는 매니페스트 파일이 필요합니다. 파일 이름을 AndroidManifest.xml
로 지정하고 테스트 모듈용 Android.mk
옆에 제공하면 BUILD_PACKAGE
코어 메이크파일에 의해 자동으로 포함됩니다.
더 진행하기 전에 먼저 앱 매니페스트 개요 를 살펴보는 것이 좋습니다.
여기에서는 매니페스트 파일의 기본 구성 요소와 해당 기능에 대한 개요를 제공합니다. platform_testing/tests/example/instrumentation/AndroidManifest.xml 에서 예제를 참조하십시오.
편의를 위해 여기에 스냅샷이 포함되어 있습니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
<application/>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.test.example.helloworld"
android:label="Hello World Test"/>
</manifest>
매니페스트 파일에 대한 일부 선택 설명:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.test.example.helloworld" >
package
속성은 애플리케이션 패키지 이름입니다. 이는 Android 애플리케이션 프레임워크가 애플리케이션(또는 이 컨텍스트에서는 테스트 애플리케이션)을 식별하는 데 사용하는 고유 식별자입니다. 시스템의 각 사용자는 해당 패키지 이름으로 하나의 응용 프로그램만 설치할 수 있습니다.
또한 이 package
속성은 ComponentName#getPackageName()
이 반환하는 것과 동일하며 adb shell
을 통해 다양한 pm
하위 명령과 상호 작용하는 데 사용하는 것과 동일합니다.
또한 패키지 이름은 일반적으로 Java 패키지 이름과 같은 스타일이지만 실제로는 관련이 거의 없습니다. 즉, 응용 프로그램(또는 테스트) 패키지에는 모든 패키지 이름을 가진 클래스가 포함될 수 있지만, 반면에 단순성을 선택하고 응용 프로그램 또는 테스트에서 응용 프로그램 패키지 이름과 동일한 최상위 Java 패키지 이름을 가질 수 있습니다.
android:sharedUserId="android.uid.system"
이는 설치 시 이 apk에 코어 플랫폼과 동일한 사용자 ID, 즉 런타임 ID가 부여되어야 함을 선언합니다. 이는 핵심 플랫폼과 동일한 인증서로 서명된 apk에 따라 다르지만(위 섹션의 LOCAL_CERTIFICATE
참조) 서로 다른 개념입니다.
- 일부 권한 또는 API는 서명으로 보호되며 동일한 서명 인증서가 필요합니다.
- 일부 권한 또는 API에는 호출자의
system
사용자 ID가 필요하며, 핵심 플랫폼 자체와 별도의 패키지인 경우 호출 패키지가system
과 사용자 ID를 공유해야 합니다.
<uses-library android:name="android.test.runner" />
이는 관련 클래스가 별도의 프레임워크 jar 라이브러리 파일에 패키지되어 있기 때문에 모든 계측 테스트에 필요하므로 애플리케이션 프레임워크에서 테스트 패키지를 호출할 때 추가 클래스 경로 항목이 필요합니다.
android:targetPackage="android.test.example.helloworld"
여기에서 targetPackage
가 이 파일의 manifest
태그에 선언된 package
속성과 동일하게 선언되었음을 알 수 있습니다. 테스트 기본 사항 에서 언급한 바와 같이 계측 테스트의 이 범주는 일반적으로 프레임워크 API를 테스트하기 위한 것이므로 자체가 아닌 특정 대상 애플리케이션 패키지를 갖는 것은 그다지 의미가 없습니다.
간단한 구성 파일
각각의 새 테스트 모듈에는 모듈 메타데이터, 컴파일 시간 종속성 및 패키징 지침으로 빌드 시스템을 지시하는 구성 파일이 있어야 합니다. 대부분의 경우 Soong 기반 Blueprint 파일 옵션으로 충분합니다. 자세한 내용은 단순 테스트 구성 을 참조하십시오.
복잡한 구성 파일
이러한 더 복잡한 경우에는 Android의 테스트 도구인 Trade Federation 에 대한 테스트 구성 파일도 작성해야 합니다.
테스트 구성은 특수 장치 설정 옵션과 기본 인수를 지정하여 테스트 클래스를 제공할 수 있습니다. /platform_testing/tests/example/instrumentation/AndroidTest.xml 에서 예제를 참조하십시오.
편의를 위해 여기에 스냅샷이 포함되어 있습니다.
<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>
테스트 구성 파일에 대한 일부 선택 설명:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
이는 지정된 target_preparer를 사용하여 대상 장치에 HelloWorldTests.apk를 설치하도록 Trade Federation에 지시합니다. Trade Federation의 개발자가 사용할 수 있는 많은 대상 준비자가 있으며 이를 사용하여 테스트 실행 전에 장치가 올바르게 설정되었는지 확인할 수 있습니다.
<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>
테스트를 실행하는 데 사용할 Trade Federation 테스트 클래스를 지정하고 실행할 장치의 패키지와 이 경우 JUnit인 테스트 실행기 프레임워크를 전달합니다.
자세한 내용은 테스트 모듈 구성 을 참조하십시오.
JUnit4 기능
android-support-test
라이브러리를 테스트 러너로 사용하면 새로운 JUnit4 스타일 테스트 클래스를 채택할 수 있으며 샘플 gerrit 변경에는 해당 기능의 매우 기본적인 사용이 포함되어 있습니다. /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java 에서 예제를 참조하세요.
테스트 패턴은 일반적으로 구성 요소 팀에 따라 다르지만 일반적으로 유용한 사용 패턴이 있습니다.
@RunWith(JUnit4.class)
public class HelloWorldTest {
JUnit4의 중요한 차이점은 테스트가 더 이상 공통 기본 테스트 클래스에서 상속할 필요가 없다는 것입니다. 대신 일반 Java 클래스로 테스트를 작성하고 주석을 사용하여 특정 테스트 설정 및 제약 조건을 나타냅니다. 이 예제에서는 이 클래스를 JUnit4 테스트로 실행해야 한다고 지시합니다.
@BeforeClass
public static void beforeClass() {
...
@AfterClass
public static void afterClass() {
...
@Before
public void before() {
...
@After
public void after() {
...
@Test
@SmallTest
public void testHelloWorld() {
...
@Before
및 @After
주석은 사전 테스트 설정 및 사후 테스트 해제를 수행하기 위해 JUnit4의 메서드에서 사용됩니다. 마찬가지로 @BeforeClass
및 @AfterClass
주석은 테스트 클래스의 모든 테스트를 실행하기 전에 설정을 수행하고 나중에 해제하기 위해 JUnit4의 메서드에서 사용됩니다. 클래스 범위 설정 및 해제 방법은 정적이어야 합니다. 테스트 메서드의 경우 이전 버전의 JUnit과 달리 더 이상 메서드 이름을 test
로 시작할 필요가 없으며 대신 각 메서드에 @Test
주석을 달아야 합니다. 일반적으로 테스트 메서드는 공개되어야 하며 반환 값을 선언하지 않고 매개 변수를 사용하지 않으며 예외를 throw할 수 있습니다.
중요 : 테스트 메서드 자체에 @Test
주석이 추가됩니다. APCT를 통해 테스트를 실행하려면 테스트 크기로 주석을 달아야 합니다. 예를 들어 주석이 달린 testHelloWorld
as @SmallTest
메서드입니다. 주석은 메서드 범위 또는 클래스 범위에서 적용될 수 있습니다.
instrumentation
액세스
기본 Hello World 예제에서는 다루지 않았지만 Android 테스트에서 Instrumentation
인스턴스에 대한 액세스를 요구하는 것은 매우 일반적입니다. 이는 애플리케이션 컨텍스트, 활동 수명 주기 관련 테스트 API 등에 대한 액세스를 제공하는 핵심 API 인터페이스입니다.
JUnit4 테스트에는 더 이상 공통 기본 클래스가 필요하지 않기 때문에 더 이상 InstrumentationTestCase#getInstrumentation()
을 통해 Instrumentation
인스턴스를 얻을 필요가 없습니다. 대신 새 테스트 러너는 InstrumentationRegistry
를 통해 인스턴스를 관리합니다. 여기서 계측 프레임워크에 의해 생성된 컨텍스트 및 환경 설정이 저장됩니다.
InstrumentationRegistry
클래스의 인스턴스에 액세스하려면 Instrumentation
클래스에서 정적 메서드 getInstrumentation()
을 호출하기만 하면 됩니다.
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
로컬에서 빌드 및 테스트
가장 일반적인 사용 사례의 경우 Atest 를 사용하십시오.
더 많은 사용자 정의가 필요한 더 복잡한 경우에는 계측 지침 을 따르십시오.