• 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安装
    
  • 相关阅读:
    Java学习笔记day01
    对有序数组进行二分查找(折半查找)
    对数组进行冒泡排序
    LeetCode #344. Reverse String
    LeetCode #292. Nim Game
    LeetCode #258. Add Digits
    Android DiskLruCache完全解析,硬盘缓存的最佳方案
    Android源码解析——LruCache
    Messenger与AIDL的异同
    Android应用层View绘制流程与源码分析
  • 原文地址:https://www.cnblogs.com/xiaozhuangAna/p/12103318.html
Copyright © 2020-2023  润新知