5 测试
流程图如下,
CtsTest中的Run方法如下,
//获取所有测试项包名
Map<String, Set<String>> prerequisiteApks = getPrerequisiteApks(mTestPackageList, abiSet);
//获取所有测试项的apk
Collection<String> uninstallPackages = getPrerequisitePackageNames(mTestPackageList);
try {
// always collect the device info, even for resumed runs, since test will likely be
// running on a different device
collectDeviceInfo(getDevice(), mCtsBuild, listener);
preRebootIfNecessary(mTestPackageList);// 是否需要重启
•••
// 测试项逐个进行测试
for (int i = mLastTestPackageIndex; i < mTestPackageList.size(); i++) {
TestPackage testPackage = mTestPackageList.get(i);
if (currentAbi == null ||
!currentAbi.getName().equals(testPackage.getAbi().getName())) {
currentAbi = testPackage.getAbi();
// 预装apk
installPrerequisiteApks(
prerequisiteApks.get(currentAbi.getName()), currentAbi);
}
•••
forwardPackageDetails(testPackage.getPackageDef(), listener);
test.run(filterMap.get(testPackage.getPackageDef().getId())); //进行测试
••••
}
••••
uninstallPrequisiteApks(uninstallPackages); // 卸载所有安装的apk
CTS进行测试时,测试都是通过apk的形式完成的。首先安装测试的apk,然后启动apk进行测试,测试完成之后再卸载apk。
根据测试项查找对应的apk以及卸载apk在此就不论述了,都是通过device完成。主要论述测试过程。
这个test是IremoteTest对象, IremoteTest是一个接口,到底是哪个类的对象呢?
该test对象在TestPackageDef 的createTest方法中创建,
public IRemoteTest createTest(File testCaseDir) {
mTestFilter.setTestInclusion(mClassName, mMethodName);
mTests = filterTests();
if (HOST_SIDE_ONLY_TEST.equals(mTestType)) {
CLog.d("Creating host test for %s", mName);
JarHostTest hostTest = new JarHostTest();
if (mTimeoutInMins >= 0) {
CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
hostTest.setTimeout(mTimeoutInMins * 60 * 1000);
}
hostTest.setRunName(mAppPackageName);
hostTest.setJarFileName(mJarPath);
hostTest.setTests(mTests);
hostTest.setAbi(mAbi);
mDigest = generateDigest(testCaseDir, mJarPath);
return hostTest;
} else if (VM_HOST_TEST.equals(mTestType)) {
CLog.d("Creating vm host test for %s", mName);
VMHostTest vmHostTest = new VMHostTest();
vmHostTest.setRunName(mAppPackageName);
vmHostTest.setJarFileName(mJarPath);
vmHostTest.setTests(mTests);
vmHostTest.setAbi(mAbi);
mDigest = generateDigest(testCaseDir, mJarPath);
return vmHostTest;
} else if (DEQP_TEST.equals(mTestType)) {
DeqpTestRunner deqpTest = new DeqpTestRunner(mAppPackageName, mName, mTests);
deqpTest.setAbi(mAbi);
return deqpTest;
} else if (NATIVE_TEST.equals(mTestType)) {
GeeTest geeTest = new GeeTest(mAppPackageName, mName);
geeTest.setAbi(mAbi);
return geeTest;
} else if (WRAPPED_NATIVE_TEST.equals(mTestType)) {
CLog.d("Creating new wrapped native test for %s", mName);
WrappedGTest wrappedGeeTest = new WrappedGTest(mAppNameSpace, mAppPackageName, mName, mRunner);
wrappedGeeTest.setAbi(mAbi);
return wrappedGeeTest;
} else if (ACCESSIBILITY_TEST.equals(mTestType)) {
AccessibilityTestRunner test = new AccessibilityTestRunner();
return setInstrumentationTest(test, testCaseDir);
} else if (PRINT_TEST.equals(mTestType)) {
PrintTestRunner test = new PrintTestRunner();
return setPrintTest(test, testCaseDir);
} else if (ACCESSIBILITY_SERVICE_TEST.equals(mTestType)) {
@SuppressWarnings("deprecation")
AccessibilityServiceTestRunner test = new AccessibilityServiceTestRunner();
return setInstrumentationTest(test, testCaseDir);
} else if (DISPLAY_TEST.equals(mTestType)) {
DisplayTestRunner test = new DisplayTestRunner();
return setInstrumentationTest(test, testCaseDir);
} else if (UIAUTOMATOR_TEST.equals(mTestType)) {
UiAutomatorJarTest uiautomatorTest = new UiAutomatorJarTest();
return setUiAutomatorTest(uiautomatorTest);
} else if (JUNIT_DEVICE_TEST.equals(mTestType)){
CLog.d("Creating JUnit device test %s", mName);
JUnitDeviceTest jUnitDeviceTest = new JUnitDeviceTest();
jUnitDeviceTest.setRunName(mAppPackageName);
jUnitDeviceTest.addTestJarFileName(mJarPath);
jUnitDeviceTest.addRunTimeArgs(mRunTimeArgs);
jUnitDeviceTest.setTests(mTests);
jUnitDeviceTest.setAbi(mAbi);
mDigest = generateDigest(testCaseDir, mJarPath);
return jUnitDeviceTest;
} else {
CLog.d("Creating instrumentation test for %s", mName);
CtsInstrumentationApkTest instrTest = new CtsInstrumentationApkTest();
if (mTimeoutInMins >= 0) {
// as timeout cannot be set for each test,
// increase the time-out of the whole package
CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
instrTest.setTestTimeout(mTimeoutInMins * 60 * 1000);
}
return setInstrumentationTest(instrTest, testCaseDir);
}
}
根据不同测试类型创建不同的test对象,以CtsInstrumentationApkTest为例来说明测试过程。
CtsInstrumentationApkTest的run方法首先安装测试apk,然后调用父类的run方法。
RemoteAndroidTestRunner的run方法如下,
String runCaseCommandStr = String.format("am instrument -w %1$s-r %2$s %3$s", new Object[] { getRunOptions(), getArgsCommand(), getRunnerPath() });
Log.i("RemoteAndroidTest", String.format("Running %1$s on %2$s", new Object[] { runCaseCommandStr, this.mRemoteDevice.getName() }));
String runName = this.mRunName == null ? this.mPackageName : this.mRunName;
this.mParser = new InstrumentationResultParser(runName, listeners);
try
{
this.mRemoteDevice.executeShellCommand(runCaseCommandStr, this.mParser, this.mMaxTimeToOutputResponse, this.mMaxTimeUnits);
}
还是调用远程设备的命令进行测试。
mRemoteDevice是Device对象, Device继承于IDevice, IDevice继承于IshellEnabledDevice。
最后依次调用Device的executeShellCommand方法,然后调用AdbHelper的executeRemoteCommand方法。
和monkeyrunner类似,executeRemoteCommand
方法中先创建一个面向adb服务器的socket通道,然后通过发送adb协议请求的'shell:'命令获得一个adb shell
然后再把相应的adb shell命令发送到该socket。从这里可以看到,“发送adb shell命令“其实是基于”发送adb协议请求“的,
因为在发送命令之前需要先通过组织基于adb协议的请求”shell:“来获得adb shell.