前面已经写过一个封装定位了,但是可能在yaml中书写的时候过于繁琐,以及如果代码基础较差的同学,也没有办法进行编写测试用例。就重新进行封装一次定位
页面元素写入yaml
上一篇写的yaml可能有点杂乱,这次我们换个写法
把一个页面上元素编写上去,这里没有写验证码的操作了。
# appium.yaml
LoginPage:
dec: 登录
locators:
-
name: 用户名
type: id
value: com.taobao.taobao:id/aliuser_login_mobile_et
-
name: 密码
type: android
value: resourceId("com.taobao.taobao:id/aliuser_register_sms_code_et")
-
name: 登录按钮
type: className
value: android.widget.Button
我们可以进行通过yaml读取,如果猜的没错的话,肯定是列表包含字典形式。
# read_yaml.py
import
yaml
import os
class GetYaml():
def __init__(self,file_path):
# 判断文件是否存在
if os.path.exists(file_path):
self.file_path = file_path
else:
print('没有找到%s文件路径'%file_path)
self.data = self.read_yaml()
def read_yaml(self):
with open(self.file_path,'r',encoding='utf-8')as f:
p = f.read()
return p
def get_data(self,key=None):
result = yaml.load(self.data,Loader=yaml.FullLoader)
if key == None:
return result
else:
return result.get(key)
if __name__ == '__main__':
read_yaml = GetYaml('E:/appium_python/config/appium.yaml')
xx = read_yaml.get_data('LoginPage')
print(xx['locators'])
[{'name': '用户名', 'type': 'id', 'value': 'com.taobao.taobao:id/aliuser_login_mobile_et'}, {'name': '密码', 'type': 'android', 'value': 'resourceId("com.taobao.taobao:id/aliuser_register_sms_code_et")'}, {'name': '登录按钮', 'type': 'className', 'value': 'android.widget.Button'}]
这里我们可以思考一个问题,上面元素以字典的形式存在的,那么我们可以不可以把请求定位方法的时候,直接把字典放进去,然后获取到元素坐标,定位方法,直接进行了。顺便把点击,输入等关键字一起封装进去?这样不就可以直接写了么?
封装定位方法
这里我们还安装以前的封装定位,不过这里传入的参数变成字典形式
# Base.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECfrom common.read_yaml import GetYaml
class BaseApp:
def __init__(self, driver):
self.driver = driver
def find(self, locator):
if not isinstance(locator, dict):
print('定位参数locator传值不对,必须传入字典,如: {"name": "输入账号", "by": "id", "value": "xxx"}')
if "name" in locator:
print("正在操作元素名称\"%s\"" %locator['name']+",定位方法: %s-->%s"% (locator['type'], locator['value']))
if locator["type"] == "id":
value = locator["value"]
element = WebDriverWait(self.driver, 10, 0.5).until(lambda x: x.find_element_by_id(value))
elif locator["type"] == "android":
value = locator["value"]
element = WebDriverWait(self.driver, 10, 0.5).until(lambda x: x.find_element_by_android_uiautomator(value))
elif locator["type"] == 'className':
value = locator['value']
element = WebDriverWait(self.driver, 10, 0.5).until(lambda x: x.find_element_by_class_name(value))
elif locator["type"] == "text":
value = "//*[@text='%s']" % locator["value"]
_loc = ("xpath", value)
element = WebDriverWait(self.driver, 10, 0.5).until(EC.presence_of_element_located(_loc))
else:
loc = (locator["type"], locator["value"]) # 元祖
element = WebDriverWait(self.driver, 10, 0.5).until(EC.presence_of_element_located(loc))
return element
def get_element(self,path,key):
'''读取元素'''
yaml_data = GetYaml(path)
local = yaml_data.get_data(key)
return local
def click(self, locator):
'''点击元素'''
el = self.find(locator)
el.click()
def send_text(self, locator, text):
'''发送文本'''
el = self.find(locator)
el.send_keys(text)
提取页面元素
现在写代码都遵循的PO模型,我们把页面的元素也全部都提取出来,方便写用例的时候直接进行获取
# coding:utf-8
# login_page2.py
from common.Base import BaseApp
import os
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from common.appium_start import Android_device
path =os.path.dirname(os.getcwd())
# 获取到yaml文件路径,
yaml_path = os.path.join(os.path.join(path,'config'),'appium.yaml')
class Login_element:
def __init__(self,driver):
self.driver = driver
self.get_element = BaseApp(self.driver)
def user_element(self):
''' 获取用户名元素'''
element = self.get_element.get_element(yaml_path,'LoginPage')['locators'][0]
return element
def password_element(self):
''' 获取密码元素'''
element = self.get_element.get_element(yaml_path,'LoginPage')['locators'][1]
return element
def login_boot(self):
''' 获取登录按钮元素'''
element = self.get_element.get_element(yaml_path,'LoginPage')['locators'][2]
return element
def toast(self,message):
'''获取toast信息'''
tost_element = ("xpath","//*[contains(@text,"+message+")]")
element = WebDriverWait(self.driver,10,0.1).until(EC.presence_of_element_located(tost_element)).text
return element
编写用例
前面需要封装的都写好了,然后这里我们在unittest的情况下编写登录的用例
# case.py
from
common.Base import BaseApp
from common.appium_start import Android_device,start
from pages.login_page2 import Login_element
import unittest
import threading
import time
class BaseDriver(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = Android_device()
cls.app = BaseApp(cls.driver)
cls.element = Login_element()
def test_01(self):
'''账号密码错误'''
self.app.send_text(self.element.user_element(),'1111')
self.app.send_text(self.element.password_element(),'2222')
self.app.click(self.element.login_boot())
element = self.element.toast('手机号')
self.assertIn(element,'请输入正确的手机号')
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == '__main__':
# 启动 appium
t1 = threading.Thread(target=start)
t1.start()
time.sleep(20)
# 启动用例
t2 = threading.Thread(target=unittest.main())
print(t2)
t2.start()
这样比上次的封装稍微好一点,但是我相信也肯定有更好的解决方法,小伙伴们可以一起分享出来共同学习
感谢关注,哪里不懂或者写错的地方,可以下方留言,看到第一时间回复~
来源:oschina
链接:https://my.oschina.net/u/4316695/blog/4287101