zoukankan      html  css  js  c++  java
  • appium 在linux安装和使用(持续更新)

    appium V1.10 centos7.4 安装

    安装步骤

    1. 安装node

    为了得到npm(node package manager,nodejs的安装包管理工具,可以通过npm来下载appium)
    一定要去官网下载最新的node,否则用yum install可能拿到较旧版本,导致后面安装出问题:https://nodejs.org/en/download/
    如我是linux系统,选择最新的node-v10.15.0-linux-x64.tar.xz 下载,解压:tar -xvf node-v10.15.0-linux-x64.tar.xz
    由于node是免安装版,又不是放在$PATH目录,所以要做个软链接,或者把当前路径加到$PATH,我选择第一种

    [clouder@ana53 soft]$ cd node-v10.15.0-linux-x64/bin/
    [clouder@ana53 bin]$ sudo ln -s `pwd`/node /usr/bin/
    [clouder@ana53 bin]$ sudo ln -s `pwd`/npm /usr/bin/
    
    2.安装cnpm

    由于npm的服务器在国外,由于长城防火墙原因,下载会超时,使用cnpm(npm.org的完整镜像)
    官方网址:http://npm.taobao.org
    -g 表示全局安装

    npm install cnpm -g --registry=https://registry.npm.taobao.org
    
    3.安装appium

    现在我们就可以用cnpm安装,用法跟npm一样

    cnpm install -g appium
    cnpm install -g appium-doctor
    
    4.安装appium-desktop

    Appium Desktop是一款用于Mac、Windows和Linux的开源应用。它是Appium更为优化的图形界面和appium相关的工具的组合:Appium-server的图形界面。可以设置选项、启动/停止服务器、查看日志等功能;且无须提前安装Node / NPM,因为Node运行时直接与Appium Desktop绑定。可以使用Inspector来查看应用程序的元素,并进行基本的交互。
    Appium Desktop与Appium不是同一个东西。Appium Desktop是对于Appium而言,是一个拥有更多相关工具的图形化界面。它们各自有各自的Cadence和版本控制系统。

    https://github.com/appium/appium-desktop/releases/tag/v1.10.0 下载appium-desktop-1.10.0-x86_64.AppImage,
    chmod +x appium-desktop-1.10.0-x86_64.AppImage
    sudo ln -s `pwd`/appium-desktop-1.10.0-x86_64.AppImage /usr/bin/appium-desktop
    appium-desktop 即可运行
    

    troubleshooting

    1.运行报错
    selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Could not find aapt Please set the ANDROID_HOME environment variable with the Android SDK root directory path.
    

    修改,并source一下 ~/.bashrc,

    export ANDROID_HOME=/home/clouder/soft/android/android-sdk-linux
    export ANDROID_SDK_HOME=/home/clouder/soft/android/android-sdk-linux
    export BREW_HOME=/home/linuxbrew/.linuxbrew/bin
    export PATH=$ANDROID_HOME:$ANDROID_SDK_HOME:$BREW_HOME:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools:$PATH:/home/clouder/soft/android/android-sdk-linux/build-tools/28.0.3/
    

    发现输入aapt命令是找得到命令的,修改代码,把desire_caps['automationName'] = 'UiAutomator2' 一行注释,根据https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md
    的介绍,该参数默认值是appium,android是非必须的,可能因为androd8.0以上无法用uiautomatorview导致的。

    desire_caps = {}
    desire_caps['platformName'] = 'Android'
    desire_caps['platformVersion'] = '8.1.0'
    desire_caps['deviceName'] = '35eb25e5'
    desire_caps['appPackage'] = 'onecloud.cn.xiaohui.qa'
    desire_caps['appActivity'] = 'onecloud.cn.xiaohui.main.LoadingActivity'
    #desire_caps['automationName'] = 'UiAutomator2'
    desire_caps['noReset'] = 'True'
    
    2.swipe滑动的介绍

    https://www.cnblogs.com/dsy-sun/p/6595164.html

    3.send_keys()输入中文

    在desired_caps加入一个参数"unicodeKeyboard = True ",如

    [honor9]
    platformName = Android
    platformVersion = 8.0.0
    deviceName = 37KRX18926031940
    appPackage = onecloud.cn.xiaohui.qa
    appActivity = onecloud.cn.xiaohui.main.LoadingActivity
    noReset = True
    unicodeKeyboard = True
    
    4.获取toast提示:

    但是在我环境,可能因为toast出现太快,不到1秒就消失,来不及定位.所以总是报超时.在linux环境下,由于desired_caps加了automationName=Uiautomator2会报错:

    [debug] [MJSONWP] Encountered internal error running command: Error: Could not sign with default certificate. Original error Command '/usr/local/jdk1.8.0_151/bin/java -jar /tmp/.mount_appiumNtacdY/resources/app/node_modules/appium-adb/jars/sign.jar /tmp/.mount_appiumNtacdY/resources/app/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk --override' exited with code 1
    [debug] [MJSONWP]     at ADB.apkSigningMethods.signWithDefaultCert (/tmp/.mount_appiumNtacdY/resources/app/node_modules/appium-adb/lib/tools/apk-signing.js:124:13)
    
    

    在我的windows环境,加此参数不会有此问题,但是也是拿不到toast内容.于是放弃.

    网上别人的方法:
    toast_loc=("xpath",".//*[contains(@text,'默认')]")
    
    e1=WebDriverWait(self.driver,20,0.1).until(EC.presence_of_element_located(toast_loc))
    
        def get_toast_text(self, text, timeout=5, poll_frequency=0.01):
                """
                ########################################
                描述:获取Toast的文本信息
                参数:text需要检查的提示信息  time检查总时间  poll_frequency检查时间间隔
                返回值:返回与之匹配到的toast信息
                异常描述:none
                ########################################
                """
                toast_element = (By.XPATH, "//*[contains(@text, " + "'" + text + "'" + ")]")
                toast = WebDriverWait(self.driver, timeout, poll_frequency).until(EC.presence_of_element_located(toast_element))
                return toast.text
    
    5.configparser.ConfigParser解析配置文件
        cf = configparser.ConfigParser()
        current_dir = os.path.dirname(os.path.realpath(__file__))
        config_dir = os.path.join(current_dir,'../../conf/config.cnf')
        cf.read(config_dir)
        cf.items('honor9')
    

    需要重写ConfigParser.optionXform()方法,因为该方法会把option全部改为小写,具体参考文章说明:https://blog.csdn.net/Ha_hha/article/details/78965011

    # -*- coding:utf-8 -*-
    from configparser import ConfigParser
    
    
    class MyConfigParser(ConfigParser):
        def __init__(self, defaults = None):
            ConfigParser.__init__(self, defaults = defaults)
    
        def optionxform(self, optionstr):
            return optionstr
    
    
    

    代码改为使用自己的模块创建一个对象.

        cf = myconfigparser.MyConfigParser()
        current_dir = os.path.dirname(os.path.realpath(__file__))
        config_dir = os.path.join(current_dir,'../../conf/config.cnf')
        cf.read(config_dir)
        cf.items('honor9')
    
    6.定位元素,找到多个元素.

    如果是用xpath定位,有多个,则可以用()[n]来获取第n个

    driver.find_element(by=By.XPATH, value='(//android.widget.ImageView[@resource-id="onecloud.cn.xiaohui.qa:id/main_tabitem_pic"])[2]')
    

    如果用id定位,有多个,则用find_elements()[n-1]来获取第n个

    driver.find_elements(by=By.ID, value='onecloud.cn.xiaohui.qa:id/main_tabitem_pic')[1]
    
    
    7.visibility_of_element_located()

    //判断该元素是否被加载在DOM中,并不代表该元素一定可见
    new WebDriverWait(driver,5).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='kw']")));

    参数中有字符串和变量组成,用'+'连接字符串,注意xpath属性值要用''括起:
    a = driver.find_elements(by=By.XPATH, value='//*[@text='+'''+desktop_name+'''+']')
    // *[ @ resource - id = onecloud.cn.xiaohui.qa:id / my_cloud_account_listitem_txt = 'test20190213171']

    8.python3 使用HTMLTestRunner模块.

    由于HTMLTestRunner模块不适合python3的语法,所以不能用pip命令安装.需要到官网下载后放到自己常用的第三方模块路径下,再做些修改后才能正常用.
    http://tungwaiyip.info/software/HTMLTestRunner.html
    下载HTMLTestRunner.py,test_HTMLTestRunner.py 到自己的python的第三方模块安装目录下,如何查看:在终端输入python3 ,import appium,help(appium),按shift+g,翻到最后一行,看到:

    FILE
        /opt/python36/lib/python3.6/site-packages/appium/__init__.py
    

    就下载的2个py放到/opt/python36/lib/python3.6/site-packages/目录,执行

    -rw-rw-r--   1 clouder clouder  24360 Feb 15 12:05 HTMLTestRunner.py
    -rw-rw-r--   1 clouder clouder   6620 Feb 15 12:05 test_HTMLTestRunner.py
    [clouder@ana53 site-packages]$ python3 test_HTMLTestRunner.py 
      File "test_HTMLTestRunner.py", line 58
        print self.MESSAGE
                 ^
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print(print self.MESSAGE)?
    
    

    参考:https://www.cnblogs.com/qiaoxin/articles/7928290.html

    修改汇总: 
    第94行,将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第766行,将uo = o.decode('latin-1')修改成uo = e
    第775行,将ue = e.decode('latin-1')修改成ue = e
    第631行,将print >> sys.stderr, '
    Time Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, '
    Time Elapsed: %s' % (self.stopTime-self.startTime))
    在Python3.4下使用HTMLTestRunner,开始时,引入HTMLTestRunner模块报错。
    

    做了修改,可以导入成功了.

    9.logging打印日志出现重复
    2019-02-15 16:54:21,826 - login - INFO - [line:39] - 个人用户验证码登录:
    2019-02-15 16:54:40,104 - login - INFO - [line:49] - 个人用户验证码登录成功
    2019-02-15 16:54:49,175 - login - INFO - [line:105] - 退出登录:
    2019-02-15 16:54:49,175 - login - INFO - [line:105] - 退出登录:
    2019-02-15 16:54:52,672 - login - INFO - [line:111] - 退出登录成功
    2019-02-15 16:54:52,672 - login - INFO - [line:111] - 退出登录成功
    2019-02-15 16:55:00,502 - login - INFO - [line:54] - 企业用户验证码登录:
    2019-02-15 16:55:00,502 - login - INFO - [line:54] - 企业用户验证码登录:
    2019-02-15 16:55:00,502 - login - INFO - [line:54] - 企业用户验证码登录:
    2019-02-15 16:55:30,105 - login - INFO - [line:68] - 企业用户验证码登录成功
    2019-02-15 16:55:30,105 - login - INFO - [line:68] - 企业用户验证码登录成功
    2019-02-15 16:55:30,105 - login - INFO - [line:68] - 企业用户验证码登录成功
    2019-02-15 16:55:39,277 - login - INFO - [line:105] - 退出登录:
    2019-02-15 16:55:39,277 - login - INFO - [line:105] - 退出登录:
    2019-02-15 16:55:39,277 - login - INFO - [line:105] - 退出登录:
    2019-02-15 16:55:39,277 - login - INFO - [line:105] - 退出登录:
    

    https://blog.csdn.net/huilan_same/article/details/51858817

     # 这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志 
    if not logger.handlers: 
    streamhandler = logging.StreamHandler() streamhandler.setLevel(logging.ERROR) 
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s') 
    streamhandler.setFormatter(formatter) 
    logger.addHandler(streamhandler)
    
    10.运行unittest执行结果总是有报错:<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
    /opt/python36/bin/python3 /home/clouder/workspace/pycharm/xiaohui/runall.py
    a
    <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> 
    Time Elapsed: 0:00:31.583516
    ..s
    ----------------------------------------------------------------------
    Ran 2 tests in 31.599s
    
    OK (skipped=1)
    
    Process finished with exit code 0
    

    修改HTMLTestRunner.py 第631行

    print(sys.stderr, '
    Time Elapsed: %s' % (self.stopTime-self.startTime))
    

    改成

    sys.stderr.write('
    Time Elapsed: %s
    ' % (self.stopTime -self.startTime))
    

    解决了~

    /opt/python36/bin/python3 /home/clouder/workspace/pycharm/xiaohui/main.py
    a
    .
    Time Elapsed: 0:00:30.968873
    .s
    ----------------------------------------------------------------------
    Ran 2 tests in 30.983s
    
    OK (skipped=1)
    
    11.切割字符串及列表转字符串
    case_auto_name = a[2].split('_')[0] + "_" + a[3] + "_" + "_".join(a[2].split('_')[1:])
    
    12.suite.addTest()时报错

    我是用另外一个脚本生成要执行的testcase列表,传递给suite.addTest(),直接传递一个值可以,但是list[0]就不行,

    Error
    Traceback (most recent call last):
      File "/opt/python36/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
        yield
      File "/opt/python36/lib/python3.6/unittest/case.py", line 605, in run
        testMethod()
      File "/home/clouder/workspace/pycharm/xiaohui/runall.py", line 40, in test_run_by_csv_defined
        suite.addTest(cases_list[0])
      File "/opt/python36/lib/python3.6/unittest/suite.py", line 47, in addTest
        raise TypeError("{} is not callable".format(repr(test)))
    TypeError: 'test_login.TestLogin("test_login_indivial_by_code")' is not callable
    
    13.pycharm 常用快捷键

    1.批量添加/取消备注:选中多行,按ctrl+/
    2.批量缩进:选择多行,按tab向右缩进,按shift+tab向左缩进
    3.调试:
    进入调试:shift+F9
    step over:F8
    step into:F7
    step into my code:ctrl+alt+F7

    4.运行当前窗口程序:ctrl+shift+F10
    5

    13.driver.window_handles

    记得要sleep一下,否则刚打开的标签页,可能没拿到新的handle,如下例,不sleep,只拿到2个handle,sleep可以拿到3个。

    sleep(3)
    print("进入项目详情,总的handle:",driver.window_handles)
    进入项目详情,总的handle: ['2147483649', '2147483660', '2147483667']
    
    #sleep(3)
    print("进入项目详情,总的handle:",driver.window_handles)
    进入项目详情,总的handle: ['2147483649', '2147483660']
    
    1. 打开浏览器标签
    driver_m.find_element_by_tag_name('html').send_keys(Keys.CONTROL+'t')
    




    20191226更新
    发现appium-desktop 1.10用不了,无法连接到appium server,使用appium-desktop的inspect工具,提示 ENETUNREACH。
    更新需要上github下载,一天都下不来,所以使用无界面的appium
    参考 https://www.cnblogs.com/windhome/p/8024835.html

    1、nodeJs安装
    apt-get install node.js
     
    2、npm安装
    apt-get install npm
     
    3、cnpm安装
    npm install -g cnpm --registry=https://registry.npm.taobao.org // -g全局安装
     
    4、appium安装
    在非root用户权限下安装
    cnpm install -g appium //appium server安装 
    cnpm install wd //appium client安装
    
  • 相关阅读:
    linux驱动开发学习一:创建一个字符设备
    如何高效的对有序数组去重
    找到缺失的第一个正整数
    .NET不可变集合已经正式发布
    中国人唯一不认可的成功——就是家庭的和睦,人生的平淡【转】
    自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
    ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误
    自己动手搭建 Redis 环境,并建立一个 .NET HelloWorld 程序测试
    ServiceStack 介绍
    一步一步实战扩展 ASP.NET Route,实现小写 URL、个性化 URL
  • 原文地址:https://www.cnblogs.com/xiaozhuangAna/p/12103318.html
Copyright © 2011-2022 走看看