appium 在linux安装和使用(持续更新)

别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述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-desktopAppium 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 ConfigParserclass 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=https://www.songbingjia.com/'(//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=https://www.songbingjia.com/'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=https://www.songbingjia.com/'//*[@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 clouder24360 Feb 15 12:05 HTMLTestRunner.py -rw-rw-r--1 clouder clouder6620 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, \'\\nTime Elapsed: %s\' % (self.stopTime-self.startTime)修改成print(sys.stderr, \'\\nTime 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.599sOK (skipped=1)Process finished with exit code 0

修改HTMLTestRunner.py 第631行
print(sys.stderr, \'\\nTime Elapsed: %s\' % (self.stopTime-self.startTime))

改成
sys.stderr.write(\'\\nTime Elapsed: %s\\n\' % (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.983sOK (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\')

【appium 在linux安装和使用(持续更新)】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安装


    推荐阅读