在阿里云移动测试上跑appium(921)

2018-08-06  本文已影响0人  Qin0821

前提

你需要一个能在本地跑通的自动化测试脚本。

踩过的坑

1. 找不到启动页

在我这里app的launch页面是welcome,展示splash两秒后进入guide页面,但由于之前没有控制好显示时间,welcome基本上是一闪而过,没有给脚本获取当前页面的时间,就会报找不到启动页的错误。
解决方案:在启动页停留一会。

2. native控件找不到

因为本地是能够找得到的,所有有可能是阿里云上面的测试机和本地的性能有差异,脚本执行到去找某一个页面的控件,但是这个页面还没加载出来,就会报找不到控件的错误。
解决方案:

self.driver.wait_activity('GuideActivity', 3)
3. 无法切换到webview的context

因为阿里云对chromeDriver做了处理,所以我们无法直接self.driver.switch_to.context(contexts[1])
解决方案:
参考录制脚本生成的脚本文件,可以直接将其AppiumLib.py复制过来,或者像我一样把切换context相关的代码复制到main.py

from appium import webdriver
import desired_capabilities
from unittest import TestCase
import unittest
import time
import os
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import shutil

不记得那些是为了解决问题而加的依赖,所以全部粘过来。

def switchToWebviewContext(self):
        contexts = self.driver.contexts
        webviewContextIndex = None
        packageName = self.driver.desired_capabilities.get("appPackage")
        self.log("INFO", "packageName is %s" % packageName)
        for index in range(0, len(contexts)):
            self.log("INFO", "context index is %s" % index)
            self.log("INFO", "context[%s] is %s" % (index, contexts[index]))
            if "WEBVIEW" in contexts[index] and packageName in contexts[index]:
                webviewContextIndex = index
                self.log("INFO", "webviewContextIndex is %s" % webviewContextIndex)
        if webviewContextIndex is not None:
            self.log("INFO", "switch to %s" % contexts[webviewContextIndex])
            self.log("INFO", "webviewContextIndex is %s" % webviewContextIndex)
            self.switchContext({"wait": 20, "contextIndex": webviewContextIndex})
 
def switchContext(self, content, wait=6):
        contexts = self.driver.contexts
        self.log(INFO, "contexts is %s" % contexts)

        if contexts is None:
            return

        contextIndex = content.get("contextIndex")
        wait = content.get("wait")
        self.log("INFO", contextIndex)
        context = contexts[contextIndex]
        
        if context is None or "NATIVE_APP" in context:
            self.driver.switch_to.context(context)
            return
        if wait is None or wait < 6:
            wait = 6

        startTime = time.time()
        hasContext = False
        while time.time() - startTime < wait:
            if "WEBVIEW" in context:
                hasContext = True
                break
            time.sleep(0.5)

        if not hasContext:
            raise Exception("no useable context found")

        # chromedriver目录
        chromedriverDir = "/usr/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/linux/chromedriver_64_2.%s"
        if self.appiumVersion > ABSOLUTE_COORDINATES_APPIUM_VERSION:
            # 1.8.0 chromedriver path
            chromedriverDir = "/appium/appium/node_modules/appium-chromedriver/chromedriver/linux/chromedriver_64_2.%s"
        # chromedriverDir = "/Users/skiluo/workspace/automation/appium-source/appium-chromedriver/chromedriver/mac/chromedriver_64_2.%s"
        # 若没有传入chromedriverExecutable,则失败
        executablePath = self.driver.capabilities.get('chromedriverExecutable')
        if executablePath is None:
            raise Exception("chromedriverExecutable path has not been set")
        defaultVersion = self.driver.capabilities.get('chromedriverDefaultVersion')
        self.log(INFO, "executablePath is %s, default version is %s" %
                 (executablePath, defaultVersion))
        if defaultVersion is not None:
            try:
                chromedriverFile = chromedriverDir % defaultVersion
                self.copyChromedriver(chromedriverFile, executablePath)
                self.driver.switch_to.context(context)
                self.log(INFO, "switch to %s" % context)
                return
            except Exception, e:
                self.log(
                    ERROR, "switch context with default version failed, %s" % str(e))
        while self.chromeDriverVersion >= 4:
            chromedriverFile = chromedriverDir % self.chromeDriverVersion
            self.copyChromedriver(chromedriverFile, executablePath)
            self.log("INFO", "use chromedriver_64_2.%s" %
                     self.chromeDriverVersion)
            try:
                self.driver.switch_to.context(context)
                self.log("RPC", "set default chromeversion %s" %
                         self.chromeDriverVersion)
                self.driver.capabilities['chromedriverDefaultVersion'] = self.chromeDriverVersion
                break
            except Exception, e:
                pass
            self.chromeDriverVersion -= 1

        if self.chromeDriverVersion < 4:
            raise Exception("no suitable chromedriver")

    def copyChromedriver(self, srcFile, destFile):
        # kill chromedriver before copy
        os.system("pkill chromedriver")
        if os.path.exists(srcFile):
            shutil.copy(srcFile, destFile)
        else:
            raise Exception("chrome executable file not found")

def log(self, level, info):
    print("%s : %s" % (level, info))

在需要切换到webcontext的地方直接调用即可:

self.switchToWebviewContext()

吐槽

至此,我终于在阿里云上面跑通了登录脚本。
真的搞不懂了,那么大的公司,提供的文档还是以eclipse示例,都8102年了啊,完全没有参考价值。

而且明明需要用户手动对context做处理,但是文档只字未提,发工单也不回,我只能不停的百度和谷歌,耽误我好几天,最后不停的发工单才拉了个小群讨论,每次讨论完都基本上是说自己设备可能有问题,需要看一下,然后我又得等。

有这么多坑就算了,费用还贼贵,五百块测五十次,ios价格还翻倍,由于是老大购买的,我不知道价格,几天500块就没了,现在都是一台一台的测试脚本是否通了,通了才敢多台设备一起测。

上一篇下一篇

猜你喜欢

热点阅读