一:搭建appium环境

1、JDK和Android SDK配置

2、安装Node.js

3、安装.net framework

4、安装Appium

5、安装appium - python - client

google教程很多,可以参照网上的教程,这里就不赘述了。最后使用appium-doctor检测环境搭建是否ok。

这篇文章主要介绍下基础函数的封装。

二:让appium跑起来

打开appium-server(我这里版本是V1.10.0),点击:Start Server:

1.png

进到如下这个界面,然后点击页面右上角的放大镜:

3.png

进到appium-server的基础信息设置界面,点击Saved Capability Sets:

2.png

这里面可以配置物理机或者模拟器的设备信息,然后开始一个session,需要配置的信息如下:

capabilities = {

"platformName": "Android",

"deviceName": "0acfd8d5",

"appActivity": "com.imooc.component.imoocmain.splash.MCSplashActivity",

"appPackage": "cn.com.open.mooc",

"noReset": "true"#在当前 session 下不会重置应用的状态。默认值为 false,设置为true后,不需要每次运行用例都安装apk(特别是有开屏页的app,不需要每次都经过开屏页,打开app直接进入主页)

}

根据appium版本不同,可能有些参数不是必须的,但是能加上就加上,避免出现问题。其中deviceName可以通过在cmd(windows)窗口下执行adb devices 获取,前提是要先打开设备的调试模式以及windows电脑需要具备adb环境;appActivity和appPackage的获取有很多种方法获取,这里有两种情况:第一种是本地有apk包的情况下,那么直接使用命令aapt dump badging XXX.apk(后面是apk包的绝对路径);第二种情况是没有apk包,但是模拟器或者真机上安装了应用,这时候可以使用adb logcat >c:\log.txt,把app的启动日志输出到本地的log文件,然后去log文件过滤查找,如何过滤查找关键字,这个百度也有,我一般是过滤START或者cmp关键字,后面一般跟的就是apk的Activity和Package名称(不推荐使用这个方法,因为我在多次尝试的过程中遇到华为手机有一个坑爹的问题,就是系统日志默认是关闭的,需要输入一串命令来打开log开关:*#*#2846579#*#*,进入projectmenu--后台设置--LOG设置--LOG开关--打开,最终以失败告终);或者使用adb logcat | grep START命令(windows使用findstr过滤),在cmd窗口输入这个命令后,启动app,然后查看cmd窗口输出的日志

4.png

可以看到输出的日志中,有一个LAUNCHER关键字,后面紧接着flg=0x10200000cmp=cn.com.open.mooc/com.imooc.component.imoocmain.splash.MCSplashActivity中的cn.com.open.mooc就是包名,com.imooc.component.imoocmain.splash.MCSplashActivity就是启动页的Activity(推荐使用这种方法)。

准备工作做完之后,在appium-server的基础信息设置界面选择一个自己已保存的设备,然后点击start session,就可以看到appium-server端有日志输出,这个日志很重要,后续可以作为调试信息来定位问题,同时也能看到手机也就运行起了相应的apk(整个过程都是需要打开调试模式的)

三、页面滑动初级使用

appium的滑动函数是:driver.swipe(x,y,x1,y1,time)。起始点:x,y;终点x1,y1;time是可选参数,左右滑动Y坐标不变,X变化;上下滑动X坐标不变,Y变化。appium中的坐标和数学的坐标不同,appium坐标原点在界面左上角。

滑动函数的封装:

代码和数据分离可以有效减少由于数据变化而维护代码的成本,所以封装一个获取手机屏幕大小和滑动的类,达到的效果是:只需要告诉程序我想要滑动的方向即可,滑动坐标的起始点并不需要关心。

代码实现:

from appium import webdriver

from time import sleep

capabilities = {

"platformName": "Android",

#"automationName":"Uiautomator2",#获取toast元素需要的

"deviceName": "0acfd8d5",

"appActivity": "com.imooc.component.imoocmain.splash.MCSplashActivity",

# "appWaitActivity":"cn.com.open.mooc.index.splash.GuideActivity"#真机启动页等待

"appPackage": "cn.com.open.mooc",

"noReset": "true"#在当前 session 下不会重置应用的状态。默认值为 false,设置为true后,不需要每次运行用例都安装apk

}

class getSizeAndSwipe():

def __init__(self):#构造函数,实例化类的对象时调用

self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", capabilities)

self.size = self.driver.get_window_size()#获取屏幕的大小,返回的形式是{'width': 1080, 'height': 1812}

self.width = self.size["width"]#获取宽

self.height = self.size["height"]#获取高

def swipeUp(self):

x1 = self.width / 2

y1 = self.height / 10 * 9#获取高的十分之九的位置

x2 = x1

y2 = self.height / 10 * 1#获取十分之一的位置

self.driver.swipe(x1,y1,x2,y2)#向上滑动x坐标不变,y坐标变小

def swipeDown(self):

x1 = self.width / 2

y1 = self.height / 10 * 1

x2 = x1

y2 = self.height / 10 * 9

self.driver.swipe(x1, y1, x2, y2)

def swipeRight(self):

x1 = self.width / 10 * 1

y1 = self.height / 2

x2 = self.width / 10 * 9

y2 = y1

self.driver.swipe(x1, y1, x2, y2)

def swipeLeft(self):

x1 = self.width / 10 * 9

y1 = self.height / 2

x2 = self.width / 10 * 1

y2 = y1

self.driver.swipe(x1, y1, x2, y2)

def swipeAction(self,direction):#定义一个滑动函数,传入一个方向即可

if direction == "up":

self.swipeUp()

elif direction == "down":

self.swipeDown()

elif direction == "left":

self.swipeLeft()

else:

self.swipeRight()

if __name__ == "__main__":

vivoSwipe = getSizeAndSwipe()

vivoSwipe.swipeAction("up")#告知滑动的方向即可

四、元素定位

1、id定位

2、class_name定位

3、层级定位

4、uiautomator定位

5、Xpath定位

6、原生页面和webview页面切换,以及toast元素获取

封装一个登陆页面元素定位的类,每种定位方式封装为一个方法,代码实现:

from appium import webdriver

from time import sleep

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

capabilities = {

"platformName": "Android",

"automationName":"Uiautomator2",#获取toast元素需要的

"deviceName": "0acfd8d5",

"appActivity": "com.imooc.component.imoocmain.splash.MCSplashActivity",

# "appWaitActivity":"cn.com.open.mooc.index.splash.GuideActivity"#真机启动页等待

"appPackage": "cn.com.open.mooc",

"noReset": "true"#在当前 session 下不会重置应用的状态。默认值为 false,设置为true后,不需要每次运行用例都安装apk

}

class handleLoginElement():

def __init__(self):

self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",capabilities)#初始化driver

def goLoginById(self):#id定位的方式登陆

bottoms = self.driver.find_elements_by_id("cn.com.open.mooc:id/lav")#底部的四个按钮(首页,手记,我的学习,账号的id属性是一样的,先找出所有的,然后再通过索引查找需要的元素)

count = bottoms[3]#账号元素的索引为3

count.click()#做一个点击操作

sleep(1)

self.driver.find_element_by_id("cn.com.open.mooc:id/rl_login_before").click()

self.driver.find_element_by_id("cn.com.open.mooc:id/right_text").click()#若是已有账号,那么直接点击登陆跳转到登陆界面;非首次登陆,不需要这一步,点击登陆会直接跳转到登陆界面

self.driver.find_element_by_id("cn.com.open.mooc:id/accountEdit").clear()#先清理一下默认的上次输入过的文本

self.driver.find_element_by_id("cn.com.open.mooc:id/accountEdit").send_keys("15555555555")#输入

self.driver.find_element_by_id("cn.com.open.mooc:id/passwordEdit").clear()

self.driver.find_element_by_id("cn.com.open.mooc:id/passwordEdit").send_keys("XXXX")

self.driver.find_element_by_id("cn.com.open.mooc:id/loginLabel").click()#点击登陆

sleep(2)

def goLoginByClassName(self):#name定位的方式登陆

bottoms = self.driver.find_elements_by_class_name("android.widget.ImageView")

print(len(bottoms))#可以打印看下找到了几个name属性为android.widget.ImageView的元素

count = bottoms[25]

count.click()

sleep(1)

self.driver.find_elements_by_class_name("android.widget.TextView")[0].click()#通过索引来操作元素

#第二次登陆,没有上面的这一步self.driver.find_element_by_id("cn.com.open.mooc:id/right_text").click()

self.driver.find_elements_by_class_name("android.widget.EditText")[0].clear()

self.driver.find_elements_by_class_name("android.widget.EditText")[0].send_keys("15555555555")

self.driver.find_elements_by_class_name("android.widget.EditText")[1].clear()

self.driver.find_elements_by_class_name("android.widget.EditText")[1].send_keys("XXXX")

self.driver.find_elements_by_class_name("android.widget.TextView")[2].click()

sleep(2)

def goLoginByUiAutomator(self):

bottoms = self.driver.find_elements_by_android_uiautomator('new UiSelector().resourceId("cn.com.open.mooc:id/lav")')

count = bottoms[3]

count.click()

sleep(1)

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.TextView")')[0].click()

self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("cn.com.open.mooc:id/right_text")').click()#若是已有账号,那么直接点击登陆跳转到登陆界面;非首次登陆,不需要这一步,点击登陆会直接跳转到登陆界面

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.EditText")')[0].clear()

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.EditText")')[0].send_keys("15555555555")

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.EditText")')[1].clear()

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.EditText")')[1].send_keys("XXXX")

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.TextView")')[2].click()

sleep(2)

def goLoginByXpath(self):

# self.driver.find_elements_by_xpath('//*[contains(@text,"账号")]')[1].click()#写法一,找到页面上text属性包含“账号“的元素

# self.driver.find_element_by_xpath('//android.widget.TextView[@text="账号"]').click()#写法二,找到页面上classname为android.widget.TextView并且text属性等于”账号”的元素

self.driver.find_element_by_xpath('//android.widget.TextView[@text="账号"]/../../preceding-sibling::*[@index="2"]').click()#定位页面上classname为android.widget.TextView并且text等于”账号”的元素;/../../代表向上两个层级,preceding-sibling代表兄弟节点,意思是找到兄弟节点下面index=2的元素

def getWebView(self):#原生和H5页面之间的切换

webview = self.driver.contexts

print(webview)#打印看下当前的上下文窗口有几个,获取要切换的窗口

for view in webview:

if view == "XXX":#XXX是要切换过去的窗口

self.driver.switch_to.content(view)

break

def getToast(self):

sleep(1)

bottoms = self.driver.find_elements_by_id("cn.com.open.mooc:id/lav") # 底部的四个按钮(首页,手记,我的学习,账号的id属性是一样的,先找出所有的,然后再通过索引查找需要的元素)

count = bottoms[3] # 账号元素的索引为3

count.click() # 做一个点击操作

sleep(1)

self.driver.find_elements_by_class_name("android.widget.TextView")[0].click() # 通过索引来操作元素

self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("cn.com.open.mooc:id/right_text")').click()

self.driver.find_elements_by_class_name("android.widget.EditText")[0].clear()

self.driver.find_elements_by_class_name("android.widget.EditText")[0].send_keys("15555555555")

self.driver.find_elements_by_class_name("android.widget.TextView")[2].click()

self.driver.find_elements_by_class_name("android.widget.EditText")[1].send_keys("123456")

self.driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.TextView")')[2].click()

toast_element = ("xpath", "//*[contains(@text,'登录密码错误')]")#//代表根目录,*是通配符。表示根目录下所有text属性包含“登录密码错误”的元素

try:

toast = WebDriverWait(self.driver, 10, 0.1).until(EC.presence_of_element_located(toast_element))

print(toast.text)

except:

print("toast未找到")

if __name__ == "__main__":

handleelement = handleLoginElement()

handleelement.getToast()

其中,获取toast元素,需要

1、Appium1.6.3以上(包括1.6.3)

2、Android版本在5.0以上

引入了两个包:

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

WebDriverWait用于智能等待;expected_conditions用于直到某个条件满足

toast = WebDriverWait(self.driver, 10, 0.1).until(EC.presence_of_element_located(toast_element))

这段代码的含义是:智能等待10s,每隔0.1秒检测一次,直到某个定位元素出现为止。

appium android函数,Appium(一):appium环境以及基础函数的封装相关推荐

  1. 学习笔记(2):基于NDK、C++、FFmpeg的android视频播放器开发实战-音视频基础知识Mpeg4封装格式音视频编码格式讲解...

    立即学习:https://edu.csdn.net/course/play/7417/151027?utm_source=blogtoedu 封装:将音视频从文件中读出来 解码:解压出来,转换成显卡支 ...

  2. python语言基础实验_实验二Python语言基础函数包练习.doc

    实验二Python语言基础函数包练习 实验 Python语言基础函数包练习:1208 学号: 实验目的 1.Python语言包,如math.NumPySciPy和Matplotlib等函数包的使用实验 ...

  3. OpenCV的一些基础函数的使用——C++

    OpenCV的一些基础函数的使用--C++ 一.基础函数 1.morphologyEx的开闭运算 2.findContours查找轮廓 相关链接 获得最小外接圆.外接矩阵.轮廓面积 一.基础函数 1. ...

  4. App测试环境搭建全过程,包含JAVA JDK配置、Android SDK、、Appium、Node.js、模拟器配置【究极保姆级】还不会我吃奥利给

    目录 一.环境搭建 1.Windows的java jdk的配置 (1)下载Java的jdk,我建议用Java的1.8版本,比较稳定,我选择的也是1.8版本 JDK下载链接和网盘链接 下图是通过网址下载 ...

  5. python for android 安装配置_mac appium for android 环境搭建 (appium python pycharm)

    1. 安装 java android_home 和 java_home 环境变量配置(网上有很多教程,我配置时遇到一些坑,存在问题,后来终于搞定) 记录一下我的存在的问题,mac 下我的 cmd 升级 ...

  6. 如何用android studio测试用例,Android Studio上使用Appium创建测试用例基本步骤

    用AS创建一个空activity的工程(比如project名叫MyBaiduTest) 在工程中new module一个java Library模块(比如新建的module名叫SearchAndCli ...

  7. Appium appium android 6.0+ 微信 @driver.available_contexts 返回 webview_undefined 问题

    环境:Android 6.0.1+appium 1.4.16.1 在上面环境中执行微信公众号中的H5测试,发现driver.available_contexts 有时候返回:webview_undef ...

  8. Python+Appium+夜神模拟器 全流程从环境搭建到实现自动化(APP自动化)

    ** 文末有小礼物! ** 希望此次分享能够帮助小伙伴们,按照当前文章可自主搭建APP自动化测试环境和实现计算机控制模拟器APP执行操作! 环境依赖(jdk.sdk) 安装jdk(地址):jdk下载地 ...

  9. android app自动化测试框架Appium资料整理

    by Ruiming.Lv 1   自动化测试 1.1    自动化测试简介 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程.从广义上来讲,一切通过工具(程序)的方式来代替或辅助手工测试的 ...

最新文章

  1. mysql字段名与关键字冲突(near to:syntax error)
  2. 【Python入门】Python列表的11个方法全解
  3. JavaScript实现数乘以二multiplyByTwo算法(附完整源码)
  4. python函数的组成要素_python函数要素有哪些?这7点是你写好python代码的关键
  5. http请求中的Content-Type,详解
  6. python382怎么用_用python做UDP连接
  7. 操作系统--内核级线程实现
  8. C++ 通讯录设计(四)
  9. 计算机工程与网络学术会议怎么样,第七届计算机工程与网络国际会议(CENet2017)确保EI快速检索!...
  10. python 基础语法学习笔记(2019年4月第二周学习笔记)
  11. linux系统中用户和组的管理
  12. java语言乘号_java的编码样式、运算符运算对象
  13. 多核服务器装SQL2005,提示SQL server服务无法启动
  14. 第十章 Scala 容器基础(二十二):合并有序集合
  15. iOS UI控件(2) UITextView
  16. char *p=abc与char p[]=abc的不同
  17. C语言必背18个经典程序
  18. 微信小程序展示弹窗的几种方式
  19. Vue前端页面开发之vue2.0脚手架搭建
  20. 疫情之下,企业如何突围?

热门文章

  1. rust最低什么显卡能游戏_《腐蚀》Rust配置要求汇总 游戏配置要求是什么?
  2. 云尚办公OA系统(8.微信公众号)
  3. 生化奇兵无限服务器过于繁忙,生化奇兵3无限 困难模式10小时通关 心得分享
  4. 2022-中医基础-《阴阳 20问与答》
  5. 企业里下一代人工智能助手
  6. 开店攻略: 童装商品陈列的几大要点归纳
  7. vim 文件编辑器配色(colorscheme)主题方案
  8. html视频爱奇艺播放页面,爱奇艺视频播放列表.html
  9. 一点排位就安全异常退出_CF穿越火线新视界,版本大改动,你准备回归还是退出?...
  10. apriori-课堂笔记