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, '\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.599s OK (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.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安装

appium 在linux安装和使用(持续更新)的更多相关文章

  1. Linux 服务器命令,持续更新……

    记录一下常用命令给自己备忘备查,会持续更新-- 一.查看和修改Linux的时间 1. 查看时间和日期,命令: date 2.设定时间和日期 例如:将系统日期修改成2020年2月14日12点的命令: d ...

  2. 软件测试工程师的Linux之路(持续更新修正)

    软件测试工程师成长必经之路—Linux学习. 测试工程师不同于运维工程师,所以在对不熟悉Linux的测试人员来说,先了解一些Linux系统的基本操作,能顺利开展测试工作即可,在强迫自己使用,熟悉命令行 ...

  3. Linux 常用指令【持续更新】

    在学校的时候学过一些简单的 Linux 命令,主要是文件的创建拷贝解压等操作,最近在电脑上安装了一个CentOS6.8版本的基本版,纯命令行操作. ../ 代表上一级目录 ./ 代表本级目录 / 代表 ...

  4. Linux常用指令(持续更新)

    (这些文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) PP真的是一位很有姿势的程序猿,有这样的邻居真好,榜样啊. pwd 当前路径 df  -kh ...

  5. Linux常用命令(持续更新)

    lsb_release -a 查看linux操作系统信息 getconf LONG_BIT 查看linux操作系统位数 useradd [-g groupname] username 创建用户,并指定 ...

  6. Android Studio的安装使用记录[持续更新]

    参考资料: Windows环境下Android Studio v1.0安装教程 http://ask.android-studio.org/?/article/9 1. 下载与安装 在http://w ...

  7. linux术语解析(持续更新)

    1.linux内核有个版本,分别是 longterm: 提供长期支持的内核版本 stable: 稳定版本 Beta 测试版

  8. centos6.4安装使用wine 持续更新中

    首先,从wine的官网下载页面http://www.winehq.org/download/可以了解到centos安装wine需要EPEL软件仓库.那么首先安装EPEL软件仓库,从http://mir ...

  9. linux常用小技巧(持续更新中)

    一.设置固定ip地址1.config查看用的是哪一个网卡这是假设用的是eth12.修改dns地址vim /etc/resolv.confsearch 域名地址nameserver 192.168.3. ...

  10. Linux 特殊指令总结(持续更新)

    Linux 命令 1. 查看系统信息 1.uname uname (1) - print system information uname (2) - get name and information ...

随机推荐

  1. AWS启示录:创新作帆,云计算的征途是汪洋大海

    全文13100字,预计阅读时间15到20分钟. 开篇:创新是AWS发展的最持久驱动力 云计算,新世纪以来最伟大的技术进步之一,从2006年 Amazon Web Service(以下简称AWS)初创时 ...

  2. 爬虫笔记之xpath

    目录 xpath如何取包含多个class属性 xpath获取当前标签下的所有文本(包括子标签) xpath如何取包含多个class属性 如果HTML结构是这样 <div class=" ...

  3. 【每日一题】【迭代器,泛型】2022年1月8日-NC93 设计LRU缓存结构

    描述设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k ,并有如下两个功能1. set(key, value):将记录(key, value)插入该结构2. get(key): ...

  4. 关于Window中右键新建菜单的设置

    在日常工作中,有时候需要根据自己的需要对Windows桌面右键新建菜单进行自定义,自定义的方法如下: 1.在Window中输入Win+R调出运行命令框 2.输入regedit,打开注册表 3.如果想要 ...

  5. web框架推导 wsgiref模块 jinja2模板语法 django框架简介 django基本操作

    目录 纯手撸web框架 web框架的本质 手写web框架 存在的问题 基于wsgiref模块 基本介绍 推导流程 代码封装优化 总结 动静态网页 jinja2模块 前端.后端.数据库三者联动 推导流程 ...

  6. python注释、变量、数据类型详细

    目录 1.python注释 2.PEP8规范 3.变量与常量 1.python中的变量 2.变量名的命名规范 3.常量的基本使用 1.python注释 什么是注释? 注释是对代码的解释说明,写注释是为 ...

  7. js 非空判断

    是否为 null 是否为 "" 是否为空字符串(引号中间有空格)  如: "     ". 制表符.换行符.换页符和回车 一. 字符串 1. if(str == ...

  8. JavaScript:操作符:逻辑运算符及其隐式转换数据类型

    逻辑非! 用来对布尔值进行取反,即!true = false: 当取反的变量不是布尔值,会进行隐式转换为布尔值: 非0的数字,都转换为true 非空字符串,转换为true 非空对象,转换为true I ...

  9. (已转)Linux基础第六章 信号

    6.1 前言 本章简单描述信号.信号是Linux系统中,内核和进程通信的一种方式.如果内核希望打断进程的顺序执行,那么内核会在进程的PCB中记录信号.而当这个进程被分配到CPU,进入执行状态时,首先会 ...

  10. Django之SQL注入漏洞复现(CVE-2021-35042)

    前言 SQL注入的原理是对web请求,表单或域名等提交查询的字符串没有进行安全检测过滤,攻击者可以拼接执行恶意SQL命令,导致用户数据泄露 漏洞原理 Django 组件存在 SQL 注入漏洞,该漏洞是 ...