android自动化测试CTS源码分析之四

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.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值