在社区潜水一年多,潜水期间社区里的内容解决了我在工作中大大小小的各种问题,正好这段时间开始又重新开始研究了移动端自动化测试,就准备把自己瞎琢磨的一些东西分享给有需要的朋友吧~
appium 的环境搭建社区里已经有 hin 多 hin 详细的帖子了,可以参照这篇帖子:Appium macOS 下的 Appium 安装与配置
,这里就不多加介绍了,还没有搭建环境的或者搭建过程中碰到一些问题的,可以尝试看看这篇帖子,说不定有你想要的答案哦~
下面开始介绍目前所了解到的两种元素定位的工具吧~
uiautomatorviewer 是 Android SDK 自带的工具,mac 是在../../Library/Android/sdk/tools/bin
路径下,在目录下执行命令./uiautomatorviewer就可以愉快的用它进行元素定位了~相信大家用的都比较多的啦~
下面使用的是我厂的产品(不打广告),如下:
想知道哪里点哪里,真的是 so easy~
不过用的时候碰到这个问题:
我把模拟器重启了一下就好了,尴尬~
Appium Desktop 是在 appium 官方网站下载的,刚用的时候还有点懵逼,这特么是个什么鬼~
后来通过查找各种资料,终于会用了,可以出来显摆一下了~
入口如下图,开启 appium 服务之后,点击上面的「Start New Session」按钮,就进入到图右边的界面啦~
然后像右图一样配置好测试设备的信息,点击开始就可以进入到获取元素定位的界面,如下图:
这块功能挺好玩的,中间部分有个小眼睛的按钮,点击可以进行录制,还能把操作转成你想要的测试代码,右边还有三个操作「Tap」、「send keys」和「clear」
import unittest # 单元测试框架
from appium import webdriver # appium库
class AppTest(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = 'Android Emulator'
desired_caps['app'] = '/Users/yugui/Desktop/idxyer-v7.3.3.apk'
desired_caps['noReset'] = False
desired_caps["unicodeKeyboard"] = "True"
desired_caps["resetKeyboard"] = "True"
self.wd = webdriver.Remote('http://127.0.0.1:4725/wd/hub', desired_caps)
self.wd.implicitly_wait(60)
def test_login(self):
pass
def tearDown(self):
self.wd.quit()
if __name__ == '__main__':
unittest.main()
还是以我厂的 app 为例,想写一个登录的小 demo,但是实践过程中发现以下几个问题:
接下来就开始解决这些问题啦~
def SwipeLeft(self, duration):
# 获取手机分辨率的宽度
x = self.wd.get_window_size()['width']
# 获取手机分辨率的高度
y = self.wd.get_window_size()['height']
self.wd.swipe(x * 9/10, y/2, x/10, y/2, duration)
def findElement(self, element):
try:
WebDriverWait(self.wd, 10).until(expected_conditions.presence_of_element_located((By.ID, element)))
return True
except selenium.common.exceptions.TimeoutException:
return False
except selenium.common.exceptions.NoSuchElementException:
return False
因为元素找不到有多重原因,有可能是超时也有可能是没有这个元素,所以这里做了两个异常处理。
下面是正经的测试代码,
def test_login(self):
if self.findElement('cn.dxy.idxyer:id/start_up_welcome_image_iv'):
for i in range(3):
self.SwipeLeft(1000)
self.wd.find_element_by_id('cn.dxy.idxyer:id/start_up_welcome_enter_tv').click()
else:
print('欢迎页不存在的')
self.wd.implicitly_wait(60)
self.wd.find_element_by_id('cn.dxy.idxyer:id/main_mine_rb').click()
if self.findElement('cn.dxy.idxyer:id/tab_account'):
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_username').set_value('111111111')
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_password').set_value('111111111')
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_login').click()
else:
print('用户已登录')
到这里也差不多收工了,最后贴上完整的.py 文件:
import unittest
import selenium.common.exceptions
from appium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
class AppTest(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = 'Android Emulator'
desired_caps['app'] = '/Users/yugui/Desktop/idxyer-v7.3.3.apk'
desired_caps['noReset'] = False
desired_caps["unicodeKeyboard"] = "True"
desired_caps["resetKeyboard"] = "True"
self.wd = webdriver.Remote('http://127.0.0.1:4725/wd/hub', desired_caps)
self.wd.implicitly_wait(60)
# 向左滑动的函数
def SwipeLeft(self, duration):
x = self.wd.get_window_size()['width']
y = self.wd.get_window_size()['height']
self.wd.swipe(x * 9/10, y/2, x/10, y/2, duration)
# 当元素找不到时
def findElement(self, element):
try:
WebDriverWait(self.wd, 10).until(expected_conditions.presence_of_element_located((By.ID, element)))
return True
except selenium.common.exceptions.TimeoutException:
return False
except selenium.common.exceptions.NoSuchElementException:
return False
def test_login(self):
if self.findElement('cn.dxy.idxyer:id/start_up_welcome_image_iv'):
for i in range(3):
self.SwipeLeft(1000)
self.wd.find_element_by_id('cn.dxy.idxyer:id/start_up_welcome_enter_tv').click()
else:
print('欢迎页不存在的')
self.wd.implicitly_wait(60)
self.wd.find_element_by_id('cn.dxy.idxyer:id/main_mine_rb').click()
if self.findElement('cn.dxy.idxyer:id/tab_account'):
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_username').set_value('1111111')
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_password').set_value('1111111')
self.wd.find_element_by_id('cn.dxy.idxyer:id/sso_login').click()
else:
print('用户已登录')
def tearDown(self):
self.wd.quit()
if __name__ == '__main__':
unittest.main()
第一次写分享,感觉篇幅有那么一丢丢长,能看到这里的应该都是真爱了,如果有不足的地方希望大家可以给出改进意见哪~