前面已經寫過一個封裝定位了,但是可能在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()
這樣比上次的封裝稍微好一點,但是我相信也肯定有更好的解決方法,小伙伴們可以一起分享出來共同學習
感謝關注,哪里不懂或者寫錯的地方,可以下方留言,看到第一時間回復~