app自动化3

###app实践一    
2018.11.10学习
1. app其它一些常用的操作:
1> 手势
a> 捏(Pinch)手势即缩小:在屏幕上使用捏手势 driver.pinch(element=el)
b> 放大屏幕:在屏幕上使用放大手势 driver.zoom(element=el)
c> 滚动:scroll
**注意:不是所有的元素都有这些方法,如图片可以放大缩小**
2> 按键操作,查各键值的网址: http://blog.csdn.net/crisschan/article/details/50419963#t1
a> 按键发送(android) driver.press_keycode(键值)
**该方法只适用于android手机,ios没有这个方法**
电话键
键名 描述 键值
KEYCODE_CALL 拨号键 5
KEYCODE_ENDCALL 挂机键 6
KEYCODE_HOME 按键Home 3
KEYCODE_MENU 菜单键 82
KEYCODE_BACK 返回键 4
KEYCODE_SEARCH 搜索键 84
KEYCODE_CAMERA 拍照键 27
KEYCODE_FOCUS 拍照对焦键 80
KEYCODE_POWER 电源键 26
KEYCODE_NOTIFICATION 通知键 83
KEYCODE_MUTE 话筒静音键 91
KEYCODE_VOLUME_MUTE 扬声器静音键 164
KEYCODE_VOLUME_UP 音量增加键 24
KEYCODE_VOLUME_DOWN 音量减小键 25

控制键
键名 描述 键值
KEYCODE_ENTER 回车键 66
KEYCODE_ESCAPE ESC键 111
KEYCODE_DPAD_CENTER 导航键 确定键 23
KEYCODE_DPAD_UP 导航键 向上 19
KEYCODE_DPAD_DOWN 导航键 向下 20
KEYCODE_DPAD_LEFT 导航键 向左 21
KEYCODE_DPAD_RIGHT 导航键 向右 22
KEYCODE_MOVE_HOME 光标移动到开始键 122
KEYCODE_MOVE_END 光标移动到末尾键 123
KEYCODE_PAGE_UP 向上翻页键 92
KEYCODE_PAGE_DOWN 向下翻页键 93
KEYCODE_DEL 退格键 67
KEYCODE_FORWARD_DEL 删除键 112
KEYCODE_INSERT 插入键 124
KEYCODE_TAB Tab键 61
KEYCODE_NUM_LOCK 小键盘锁 143
KEYCODE_CAPS_LOCK 大写锁定键 115
KEYCODE_BREAK Break/Pause键 121
KEYCODE_SCROLL_LOCK 滚动锁定键 116
KEYCODE_ZOOM_IN 放大键 168
KEYCODE_ZOOM_OUT 缩小键 169

组合键
键名 描述
KEYCODE_ALT_LEFT Alt+Left
KEYCODE_ALT_RIGHT Alt+Right
KEYCODE_CTRL_LEFT Control+Left
KEYCODE_CTRL_RIGHT Control+Right
KEYCODE_SHIFT_LEFT Shift+Left
KEYCODE_SHIFT_RIGHT Shift+Right

3> 打开通知栏/摇一摇
a> 打开通知栏(android) driver.open_notifications()
b> 摇一摇 模拟摇晃设备的操作 driver.shake()
4> 琐屏/将应用切换到后台
a> 琐屏 driver.lock(秒); 解琐 driver.unlock(秒)
b> 将应用切换至后台 driver.background_app({"timeout":5})在后台5s后切换到前台; driver.background_app({"timeout":None}) 持续置于后台
5> 设置网络连接模式 driver.set_set_network_connection(1) 飞行模式;driver.set_set_network_connection(4) 移动网络

```python
import time
from appium import webdriver

desired_caps = {}
desired_caps["platformName"] = "Android"
desired_caps["platformVersion"] = "6.0"
desired_caps["deviceName"] = "Android Emulator" #该参数无实际作用意义,但是仍需配置
desired_caps["noReset"] = True
desired_caps["app"] = r"D:\柠檬班培训\VIP培训课程\1027_简历辅导+项目流程讲解+app安装\appium+模拟器\Future-release-2018.apk"
desired_caps["appPackage"] = "com.xxzb.fenwoo" #前途贷app
desired_caps["appActivity"] = "com.xxzb.fenwoo.activity.addition.WelcomeActivity"

#1.代码写好,准备发送以上信息 2. 启动appium server 3. 启动模拟机,或连接真机,能够让adb识别到
#代码 === appium server === 模拟器/真机

#连接appium server,并发送给它设备信息
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)
#driver.pinch() 缩小
#driver.zoom() 放大
#driver.press_keycode(3) #home键
#driver.press_keycode(24) #音量放大
#driver.open_notifications() #打开通知栏
#driver.set_network_connection(1) #飞行模式
#time.sleep(5)
#driver.set_network_connection(4) #移动网络

driver.set_network_connection(2) #wifi网络
net_work = driver.network_connection
print(net_work) #返回结果为6,代表所有即连接了wifi,又有手机自己的移动网络

```

2. app与web自动化差异:
相同点
1> 都是UI界面的自动化,都是站在用户的角度,从页面上来使用功能;
2> 从appium和selenium webdriver实现的角度来说:appium继承了selenium webdriver,并在其基础上增加了app特有的内容;
3> 实现原理上都是通过http通信并遵守Json wire protocol协议,向浏览器驱动程序/appium server发送要执行的命令;

不同点:
1> app页面在手机终端中,而web页面在浏览器中;
2> 元素定位方式差异:web页面的元素和app页面的元素都有属性,但是由于实现的方式不同,元素的属性也不尽相同,共用的定位方式有id,class_name,但是app不支持的方式有name,css,tag_name,app在安卓系统中有特殊的定位方式accessibility_id,android_uiautomator(包括UiSelector,UiObject,UiDevice)
3> 启动方式的差异:web系统中只需要启动对应的浏览器即可,但app中需要指明appium server地址和端口,以及告诉appium server要操作什么样的系统和app;
4> app特有一些操作,如混合h5,触屏,滑屏,toast获取等;
5> app有安装,卸载,更新检测,而web只需要浏览器中打开网址即可,无需安装部署;
6> app每个页面的功能更简单,显示区域小,所以功能对于web来说精简;
3. 在项目实战和框架方面:
1> app的自动化框架与web自动化框架保持一致,都采用PO分层设计模式,只不过app的页面变得更多了,需要适当的根据页面功能的关联性整合一下;
2> 在web框架中的basepage,截图,日志都是可以和app公用的;
3> 在自动化用例管理方面,仍都采用pytest框架;
3. PO模式框架图:
Common
Logs
HttpReport
PageLocator
PageObject
TestData
TestCase
run.py
4. 自动化框架的优化:
1> 做成一个人人都可以操作的自动化平台,在一个web页面上创造一个页面,将元素定位,操作,测试数据填写好后,直接生成可以执行的自动化脚本;
2> 通过在数据库或excel里配置元素定位,元素操作,测试数据,编写用例,之后生成相应的python脚本,从而实现自动化,这样就可以给不会写代码的人用;

5. 有用学习网站:
http://blog.csdn.net/crisschan/article/details/50419963#t1
http://developer.android.com/reference/android/view/KeyEvent.html.

###app实践二
2018.11.13
1. 调试用例时,要所有用例连续3到4次全部运行通过,才能说明脚本还算是比较稳定的;
2. 登录自动化用例分析:
1> 每次会话,重新打开app
2> 用例1:登录成功:首页 -- 我 -- 用户名页面 -- 密码页面 -- 结果:登录成功-个人页面;
用例2:用户名为空:首页面 -- 我 -- 用户名页面 -- 结果:页面弹框提示 - 无效的手机号;
用例3:用户名未注册;首页面 -- 注册/登录 -- 用户名页面 -- 结果:toast提示验证码;
3> 用例重复运行:
a> 不能记住用户状态 = 确保每次运行登录用例时,app是没有用户登录的,方法: noRest=False
b> 由于a,需要处理欢迎页面 == 欢迎页面的处理函数
c> toast处理:对于用例3,需要在启动会话时,指定automatorName=UiAutomator2
4> 启动会话有2种情况要处理: 登录时要处理欢迎页面; 投资用例必须是用户登录状态;

3. Yaml是一种简洁的非标记语言,以数据为中心,使用空白,缩进,分行组织数据,从而使用更加简洁易用;
4. Yaml基本规则:
1> 大小写敏感;
2> 使用缩进表示层级关系;
3> 禁止使用tab缩进,只能使用空格键;
4> 缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级;
5> 使用#表示注释;
6> 字符串可以不用引号标注;
5. Yaml三种结构:
1> 字典: 使用冒号(: )表示键值对,同一缩进的所有键值对属于一个map
a> 字典方式一 (注意冒号后的空格)
platformName: Android
platfromVersion: 6.0
b> 字典方式二:{platformName:Android,platformVersion:6.0}

2> 列表: 使用连字符(- )表示,注意-后的空格
a> 列表方式一
- hello
- world
b> 列表方式二: [hello,workd,12,13]

3> scalar,纯量

6. python库: PyYamla或者ruamel.yaml
1> pip3 install PyYaml
2> 读取yaml文件的数据,并转换成python对象
a> 打开yaml文件 fs=open(os.path.join(caps_dir,"caps.yaml"))
b> 使用yaml的load()函数 data_yaml = yaml.load(fs)

class_1113_demo.yaml 文件内容如下:
```yaml
platformName: Android
platfromVersion: 6.0
test:
a: 1
b: 2

list_str:
- hello
- world
- 123
- True

```

python读取上面的yaml文件内容:
```python
import yaml

fs = open("class_1113_demo.yaml")
datas = yaml.load(fs)

print(datas) #打印结果为:{'platformName': 'Android', 'platfromVersion': 6.0, 'test': {'a': 1, 'b': 2, 'list_str': ['hello', 'world', 123, True]}}

```

7. 命令行方式启动Appium
Appium我们可以通过GUI(图形化的界面启动),同时也提供给我们通过命令行方式启动
针对新版appium-desktop,我们需要安装好node.js
(各位同学都已安装了的)进入到appium启动脚本目录
C:\Users\Administrator\AppData\Local\appium-desktop\app-1.5.0(你自己的版本号)\resources\app\node_modules\appium\build\lib,
我自己的目录为:C:\Users\qiucaixia\AppData\Local\Programs\appium-desktop\resources\app\node_modules\appium\build\lib
在cmd中执行命令:node main.js即可启动appium desktop.也可以通过命令node main.js --help查看所有可使用的参数。比如设置端口和ip等。
收起

###app实践+总结
2018.11.15学习
1. 框架的扩展:
1> 通过abd命令获取设备和app的信息,从而动态的适应设备和app信息,在python中执行cmd命令,如获取当前连接的设备:os.system("adb devices")或 os.popen(adb_device"adb devices").read()
2> 自动启动appium server
3> 多线程的分布式多台设备同时测试app应用;
2. 列表滑动点击:滑动列表到指定元素,之后操作该元素,可以使用UiAutomator中的UiScrollable滚动类来将元素滚动到可见区域
```python
import time
from appium.webdriver.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from appium.webdriver.common.mobileby import MobileBy

desired_caps = {}
desired_caps["platformName"] = "Android"
desired_caps["platformVersion"] = "6.0"
desired_caps["deviceName"] = "Android Emulator" #该参数无实际作用意义,但是仍需配置
desired_caps["noReset"] = True
desired_caps["appPackage"] = "com.lemon.lemonban" #柠檬班app
desired_caps["appActivity"] = "com.lemon.lemonban.activity.WelcomeActivity"

driver = WebDriver('http://127.0.0.1:4723/wd/hub',desired_caps)
time.sleep(5)

#1. 登录柠檬班
#2. 点击题库
WebDriverWait(driver).until(EC.visibility_of_element_located((MobileBy.ID,'com.lemon.lemonban:id/navigation_tiku')))
driver.find_element_by_id('com.lemon.lemonban:id/navigation_tiku').click()

#3. 将安全测试滚动到可见区域
#列表滑动点击
#使用UiAutomator中的UiScrollable滚动类来将元素滚动到可见区域
#对象的scrollable属性要为true才代表是可以滚动的对象
#获取当前页面可滚动对象的第一个对象 new UiSelector().scrollable(true).instance(0)
#实例化一个UiScrollable对象: new UiScrollable(new UiSelector().scrollable(true).instance(0))
#调用UiScrollable类的scrollInView()方法让元素可见
ele = driver.find_element_by_android_uiautomator \
('new UiScrollable(new UiSelector().scrollable(true).instance(0)).\
scrollIntoView(new UiSelector().textMatches("安全测试").instance(0)') #将安全测试滚动到可见区域

#点击安全测试
ele.click()
``` 


posted @ 2019-02-13 00:28  宁静~朝夕  阅读(379)  评论(0)    收藏  举报