테스트 템플릿

AOSP에는 VTS 실행기의 BaseTest의 호스트 측 Python 서브클래스가 아닌 테스트 모듈을 위한 테스트 템플릿이 포함되어 있습니다.

그림 1. 테스트 템플릿 아키텍처.

개발자는 테스트 템플릿을 사용하여 이러한 테스트를 통합하는 작업을 최소화할 수 있습니다. 이 섹션에서는 VTS testcases/template 디렉터리에 있는 테스트 템플릿을 구성하고 사용하는 방법을 살펴보고 일반적으로 사용되는 템플릿의 예를 제시합니다.

BinaryTest 템플릿

BinaryTest 템플릿을 사용하면 대상 기기에서 실행되는 테스트를 VTS에 통합할 수 있습니다. 타겟 측 테스트에는 다음이 포함됩니다.

  • 기기에 컴파일되고 푸시되는 C++ 기반 테스트
  • 바이너리로 컴파일되는 타겟 측 Python 테스트
  • 기기에서 실행 가능한 셸 스크립트

이러한 테스트는 BinaryTest 템플릿의 사용 여부와 관계없이 VTS에 통합할 수 있습니다.

BinaryTest 템플릿을 사용하여 타겟 측 테스트 통합

BinaryTest 템플릿은 개발자가 타겟 측 테스트를 손쉽게 통합할 수 있도록 설계되었습니다. 대부분의 경우 AndroidTest.xml에서 몇 가지 간단한 구성 라인을 추가할 수 있습니다. VtsDeviceTreeEarlyMountTest의 구성 예:

<configuration description="Config for VTS VtsDeviceTreeEarlyMountTest.">
  ...
<test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
<option name="test-module-name" value="VtsDeviceTreeEarlyMountTest"/>
<option name="binary-test-source" value="_32bit::DATA/nativetest/dt_early_mount_test/dt_early_mount_test" />
<option name="binary-test-source" value="_64bit::DATA/nativetest64/dt_early_mount_test/dt_early_mount_test" />
<option name="test-timeout" value="5m"/>
</test>
</configuration>

이 구성에서

  • binary-test-sourcebinary-test-type은 템플릿에 따라 다릅니다.
  • 테스트 바이너리 소스의 상대적 호스트 경로를 지정하면 템플릿이 준비 작업, 파일 푸시, 테스트 실행, 결과 파싱, 정리 작업을 처리할 수 있습니다.
  • 템플릿에는 재정의할 서브클래스의 테스트 사례 생성과 관련된 메서드가 포함되어 있습니다.
  • 템플릿은 테스트 바이너리 모듈별로 하나의 테스트 사례를 가정하고, 바이너리 소스 파일 이름은 기본적으로 테스트 사례 이름으로 사용됩니다.

구성 옵션

BinaryTest 템플릿은 다음 구성 옵션을 지원합니다.

옵션 이름 값 유형 설명
binary-test-source 문자열 호스트의 vts 테스트-사례 디렉터리를 기준으로 한 바이너리 테스트 소스 경로입니다.
예: DATA/nativetest/test
binary-test-working-directory 문자열 작업 디렉터리(기기 측 경로)입니다.
예: /data/local/tmp/testing/
binary-test-envp 문자열 바이너리 환경 변수입니다.
예: PATH=/new:$PATH
binary-test-args 문자열 테스트 인수 또는 테스트 플래그입니다.
예: --gtest_filter=test1
binary-test-ld-library-path 문자열 LD_LIBRARY_PATH 환경 변수입니다.
예: /data/local/tmp/lib
binary-test-disable-framework boolean 테스트 전에 adb stop을 실행하여 Android 프레임워크를 사용 중지합니다. 예: true
binary-test-stop-native-servers boolean 테스트 중에 제대로 구성된 모든 네이티브 서버를 중지합니다. 예: true
binary-test-type 문자열 템플릿 유형. 이 템플릿에서 다른 템플릿 유형이 확장되지만, 이미 binary-test-source를 지정했으므로 이 템플릿에 이 옵션을 지정할 필요는 없습니다.

값 유형이 strings인 옵션의 경우 구성에서 옵션을 반복하여 값을 여러 개 추가할 수 있습니다. 예를 들어 VtsDeviceTreeEarlyMountTest 예에 나와 있는 대로 binary-test-source를 두 번 설정할 수 있습니다.

테스트 태그

strings 값을 갖는 옵션 앞에 테스트 태그를 접두사로 추가하고 ::을 구분 기호로 사용하여 테스트 태그를 추가할 수 있습니다. 테스트 태그는 이름은 같지만 비트율 또는 상위 디렉터리가 다른 바이너리 소스를 포함할 때 특히 유용합니다. 예를 들어, 이름은 같지만 소스 디렉터리가 다른 소스에서 파일 푸시 또는 결과 이름 충돌을 피하려면 소스에 서로 다른 태그를 지정하면 됩니다.

두 개의 dt_early_mount_test 소스가 있는 VtsDeviceTreeEarlyMountTest 예에 나와 있는 것처럼 binary-test-source에서 테스트 태그는 _32bit::_64bit:: 접두사입니다. 32bit 또는 64bit로 끝나는 태그는 자동으로 테스트를 하나의 ABI 비트율에 사용 가능한 것으로 표시합니다. 즉, 태그가 _32bit인 테스트는 64비트 ABI에서 실행되지 않습니다. 태그를 지정하지 않으면 문자열이 비어 있는 태그를 사용하는 것과 같습니다.

태그가 동일한 옵션은 그룹화되어 다른 태그로부터 분리됩니다. 예를 들어 _32bit 태그가 있는 binary-test-args는 동일한 태그를 가진 binary-test-source에만 적용되고 동일한 태그를 가진 binary-test-working-directory에서 실행됩니다. 태그에 단일 작업 디렉터리를 지정할 수 있는 binary-test-working-directory 옵션은 바이너리 테스트에서 선택사항입니다. binary-test-working-directory 옵션을 지정하지 않은 상태로 두면 각 태그에 기본 디렉터리가 사용됩니다.

태그 이름은 결과 보고서의 테스트 사례 이름에 바로 추가됩니다. 예를 들어 태그 _32bit가 있는 테스트 사례 testcase1은 결과 보고서에서 testcase1_32bit로 표시됩니다.

BinaryTest 템플릿을 사용하지 않고 타겟 측 테스트 통합

VTS의 기본 테스트 형식은 VTS 실행기의 BaseTest에서 확장된 호스트 측 Python 테스트입니다. 타겟 측 테스트를 통합하려면 먼저 테스트 파일을 기기로 푸시하고 셸 명령어를 사용하여 테스트를 실행한 다음 호스트 측 Python 스크립트를 사용하여 결과를 파싱해야 합니다.

테스트 바이너리 푸시

VtsFilePusher 타겟 준비자를 사용하여 파일을 푸시하는 것이 좋습니다. 예:

<target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
        <option name="push" value="DATA/test->/data/local/tmp/test"/>
    </target_preparer>

VtsFilePusher는 다음 작업을 실행합니다.

  1. 기기 연결을 확인합니다.
  2. 절대 소스 파일 경로를 확인합니다.
  3. adb push 명령어를 사용하여 파일을 푸시합니다.
  4. 테스트가 끝나면 파일을 삭제합니다.

또는 유사 절차를 따르는 호스트 측 Python 테스트 스크립트를 사용하여 수동으로 파일을 푸시할 수도 있습니다.

테스트 실행

파일을 기기로 푸시한 후 호스트 측 Python 테스트 스크립트에서 셸 명령어를 사용하여 테스트를 실행합니다. 예:

device = self.android_devices[0]
res = device.shell.Execute(["chmod a+x /data/local/tmp/test", "/data/local/tmp/test"])
asserts.AssertFalse(any(res[return_codes]))

GtestBinaryTest 템플릿

GtestBinaryTest 템플릿은 GTest 테스트 바이너리를 호스팅하며 각 테스트 바이너리에는 대개 여러 개의 테스트 사례가 포함되어 있습니다. 이 템플릿은 설정, 테스트 사례 생성 및 결과 파싱 메서드를 재정의하는 방식으로 BinaryTest 템플릿을 확장합니다. 따라서 모든 BinaryTest 구성이 상속됩니다.

GtestBinaryTest는 옵션 gtest-batch-mode를 추가합니다.

옵션 이름 값 유형 설명
binary-test-type 문자열 템플릿 유형. 값 gtest를 사용합니다.
gtest-batch-mode boolean Gtest 바이너리를 배치 모드로 실행합니다. 예: true

일반적으로 gtest-batch-modetrue로 설정하면 성능은 향상되지만 안정성이 약간 저하됩니다. VTS 규정 준수 테스트에서 많은 모듈이 성능 향상을 위해 배치 모드를 사용합니다. 그러나 안정성을 위해 배치 모드가 지정되지 않은 경우 기본적으로 비배치 모드가 사용됩니다.

비배치 모드

비배치 모드에서는 테스트 사례마다 GTest 바이너리를 개별적으로 호출합니다. 예를 들어 호스트 측 구성으로 필터링한 후 GTest 바이너리에 10개의 테스트 사례가 포함된 경우 바이너리는 매번 다른 테스트 필터로 기기 셸에서 10번 호출됩니다. 테스트 사례마다 고유한 GTest 결과 출력 XML이 템플릿에 의해 생성되고 파싱됩니다.

그림 2. 비배치 모드.

비배치 모드 사용 시의 장점은 다음과 같습니다.

  • 테스트 사례 분리. 한 테스트 사례의 비정상 종료 또는 중단이 다른 테스트 사례에 영향을 미치지 않습니다.
  • 세부정보. 테스트 사례별 프로파일링/커버리지 측정, systrace, bugreport, logcat 등을 더 쉽게 가져올 수 있습니다. 각 테스트 사례가 완료되면 테스트 결과와 로그를 즉시 가져오게 됩니다.

비배치 모드 사용 시의 단점은 다음과 같습니다.

  • 중복 로드. GTest 바이너리가 호출될 때마다 관련 라이브러리를 로드하고 초기 클래스 설정을 실행합니다.
  • 통신 오버헤드. 테스트가 완료되면 호스트와 대상 기기가 결과 파싱 및 그다음 명령어에 관한 통신을 실시합니다(향후에 최적화될 수 있음).

배치 모드

GTest 배치 모드에서 테스트 바이너리는 긴 테스트 필터 값(호스트 측 구성으로 필터링된 모든 테스트 사례가 포함됨)으로 한 번만 호출됩니다. 이로 인해 비배치 모드에서 발생하는 중복 로드 문제가 방지됩니다. 개발자는 output.xml 또는 터미널 출력을 사용하여 GTest의 테스트 결과를 파싱할 수 있습니다.

output.xml을 사용하는 경우(기본값):

그림 3. 배치 모드, output.xml

비배치 모드에서처럼 테스트 결과는 GTest 출력 xml 파일을 통해 파싱됩니다. 하지만 모든 테스트가 완료된 후에 출력 xml이 생성되기 때문에, 테스트 사례로 인해 바이너리 또는 기기가 비정상적으로 종료되면 결과 xml 파일이 생성되지 않습니다.

터미널 출력을 사용하는 경우:

그림 4. 배치 모드, 터미널 출력

GTest는 실행 중일 때 테스트 로그와 진행 상태를 터미널에 인쇄합니다. 이때 인쇄 형식은 테스트 상태, 결과 및 로그와 관련하여 프레임워크에 의해 파싱될 수 있는 형식입니다.

배치 모드 사용 시의 장점은 다음과 같습니다.

  • 테스트 사례 분리. 감소된 테스트 필터로 인한 비정상 종료 후 프레임워크가 바이너리/기기를 다시 시작하는 경우 비배치 모드와 동일한 수준의 테스트 사례 분리를 제공합니다(완료된 테스트 사례와 비정상 종료된 테스트 사례 제외).
  • 세부정보. 비배치 모드와 동일한 테스트 사례 세부정보를 제공합니다.

배치 모드 사용 시의 단점은 다음과 같습니다.

  • 유지관리 비용. GTest 로깅 형식이 변경되면 모든 테스트가 중단됩니다.
  • 혼동. 테스트 사례에 GTest 진행 형식과 유사한 것이 인쇄될 수 있어 형식이 혼동될 수 있습니다.

이러한 단점으로 인해 명령줄 출력을 사용할 수 있는 옵션을 일시적으로 삭제했습니다. 이 기능의 안정성을 개선하기 위해 향후에 이 옵션을 다시 논의할 예정입니다.

HostBinaryTest 템플릿

HostBinaryTest 템플릿에는 다른 디렉터리나 Python 스크립트에 없는 호스트 측 실행 파일이 포함되어 있습니다. 이러한 테스트에는 다음이 포함되어 있습니다.

  • 호스트에서 실행 가능한 컴파일된 테스트 바이너리
  • 셸, Python 또는 기타 언어로 실행 가능한 스크립트

한 가지 예는 VTS Security SELinux 정책 호스트 측 테스트입니다.

<configuration description="Config for VTS  Security SELinux policy host-side test cases">
    ...
    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
        <option name="test-module-name" value="VtsSecuritySelinuxPolicyHost"/>
        <option name="binary-test-source" value="out/host/linux-x86/bin/VtsSecuritySelinuxPolicyHostTest" />
        <option name="binary-test-type" value="host_binary_test"/>
    </test>
</configuration>

HostBinaryTest는 BinaryTest 템플릿을 확장하지 않지만 유사한 테스트 구성을 사용합니다. 위의 예에서 binary-test-source 옵션은 테스트 실행 파일의 호스트 측 상대 경로를 지정하고 binary-test-typehost_binary_test입니다. BinaryTest 템플릿과 유사하게 바이너리 파일 이름은 기본적으로 테스트 사례 이름으로 사용됩니다.

기존 템플릿 확장

테스트 구성에서 템플릿을 직접 사용하여, 비 Python 테스트를 포함하거나 특정 테스트 요구사항을 처리하는 서브클래스로 템플릿을 확장할 수 있습니다. VTS 저장소 템플릿은 다음과 같이 확장됩니다.

그림 5. VTS 저장소의 기존 템플릿 확장

개발자는 특정 테스트 요구사항에 맞게 기존 템플릿을 확장하는 것이 좋습니다. 템플릿을 확장하는 일반적인 이유는 다음과 같습니다.

  • 특수 명령어로 기기를 준비하는 등 특별한 테스트 설정 절차
  • 다른 테스트 사례 및 테스트 이름 생성
  • 명령어 결과를 읽거나 다른 조건을 사용하여 결과 파싱

기존 템플릿을 더 쉽게 확장할 수 있도록 템플릿에는 각 기능에 특화된 메서드가 포함되어 있습니다. 기존 템플릿의 디자인을 개선한 경우 VTS 코드베이스에 참여하는 것이 좋습니다.