应用场景:selenium+PO+YAML 架构的自动化测试结构
PO是Page Object ,即“页面对象模式”,是页面元素操作和业务流程相分离,代码结构比较清晰,提高了代码的复用性和降低代码维护成本。
下面按结构层进行讲述,以小米商城页面为例:
一、Base层
import yaml
# 保存页面操作中需要的公共方法
class BasePage():# 初始化页面的操作def __init__(self, driver):self.driver = drivereles = yaml.load(open('data.yaml', 'rb'), Loader=yaml.FullLoader)[self.__class__.__name__]# Loader=yaml.FullLoader是加载器,更安全,以二进制读取,获取对应的class名for ele in eles: # 根据字典动态赋值self.__setattr__(ele, eles[ele])# 点击操作def click(self, *locator):self.driver.find_element(*locator).click()# 当元素存在就点击def click_ele_exist(self, *locator):self.driver.find_element(*locator)btns = self.driver.find_elements(*locator)# 如果出现用户协议弹出按钮if btns:btns[0].click()# 输入元素定位def input_text(self, text, *locator):self.driver.find_element(*locator).send_keys(text)# 根据css定位的元素def by_js(self, css):self.driver.execute_script(f"document.querySelector('{css}')")# 切换目标窗口def switch_window(self, target_title):# 切换到产品详情页窗口for handle in self.driver.window_handles:self.driver.switch_to.window(handle)# 判断切换到窗口句柄——-判断当前窗口的标题是否是:<header>中的<title>if target_title == self.driver.title:print("切换窗口句柄到产品详情页")return True# 获取目标元素文本def get_text(self, *locator):return self.driver.find_element(*locator).textdef get_url(self, url):self.driver.get(url)# 后退def back(self):self.driver.back()# 前进def forword(self):self.driver.forword()# 退出def quit(self):self.driver.quit()
二、Common层
# ??com?mons.py文件??
# 获取项目路径、项目的各环境的url,处理数据文件的方法,框架执行相关日志功能的实现方法import os, configparser
# os: 获取操作系统级别的目录/文件夹的操作和文件的操作(读取,写入)
# configparser: 在python中的主要功能是读取配置文件config.ini# 获取config.ini路径
def congfig_path():# return os.path.split(os.path.realpath(__file__))[0].split('C')[0]# 获取当前文件的路径curPath = os.path.dirname(os.path.realpath(__file__))# 返回config.ini路径return os.path.join(curPath, "config.ini")# 返回config.ini中的testUrl
def config_url(key, value):# 创建配置文件管理对象config = configparser.ConfigParser()# 读取config.ini文件config.read(congfig_path(), encoding="utf-8")return config.get(key, value)if __name__ == '__main__':print("项目路径是:" + congfig_path())print("项目的url是: " + config_url('testUrl', 'url'))
# config.ini 文件[testUrl]
url=https://www.mi.com/index.html
# 生产环境的url地址
[productUrl]
url=https://www.mi.com/index.html
三、Data层
# 首页
IndexPage:# 前置默认空格是2个,key与值之间有1个空格login_btn: ['css selector','#J_siteUserInfo>a:nth-child(1)']user_proxy: ['css selector','.btn.btn-primary']search_input: ['id','search']# 登录页面
LoginPage:user_input: ['xpath','//input[@name="account"]']psw_input: ['xpath','//input[@name="password"]']login_btn: ['css selector','.mi-button.mi-button--primary']# 商品页面
GoodItemsPage:first_item: ['css selector','.goods-list.clearfix>div:nth-child(1) a']# 商品详情页
ItemPage:buy_btn: ['css selector','.btn.btn-small.btn-primary.J_nav_buy']# 商品认购页面
BuyPage:addCart_btn: ['css selector','.sale-btn']# 购物车页面
ShopCartPage:check_ele: ['id','J_miniHeaderTitle']
四、TestCase层
from Base.bases import BasePage
import time# 首页
class IndexPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)# 访问小米首页self.get_url('testUrl','url')# 进入登录页def to_login(self):# 点击小米首页的登录按钮self.click(*self.login_btn)# 首页————点击协议声明的同意按钮(注意:这个跳转窗口不一定每次都出现,比如只有第一次才会出现)self.click_ele_exist(*self.user_proxy)# 返回登录页对象return LoginPage(self.driver)# 搜索商品def search_item(self, item="小米11"):# 首页——搜索商品self.input_text(item+'\n', *self.search_input)return GoodItemsPage(self.driver)# 登录页面
class LoginPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)# 账户密码登录def login(self, username ,psw):# 登录页面————输入登录用户名和密码self.input_text(username, *self.user_input)self.input_text(psw, *self.psw_input)time.sleep(3)# 登录页面——点击登录按钮self.driver.find_element(*self.login_btn).click()return IndexPage(self.driver)# 商品页面
class GoodItemsPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)self.driver = driverdef pick_item(self):# 产品详情页——选中第一个商品self.click(*self.first_item)if self.switch_window('小米11 轻装上阵'):return ItemPage(self.driver)# 商品详情页
class ItemPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)self.driver = driverdef to_buy(self):# 详情页面——点击立即认购按钮self.driver.find_element(*self.buy_btn).click()if self.switch_window('小米11立即购买-小米商城'):return BuyPage(self.driver)# 商品认购页面
class BuyPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)self.driver = driverdef add_cart(self):# 认购页面——点击加入购物车按钮self.click(*self.addCart_btn)return ShopCartPage(self.driver)# 购物车页面
class ShopCartPage(BasePage):def __init__(self, driver):BasePage.__init__(self, driver)self.driver = driverdef check_item(self):# 检查是否添加购物车成功res = self.get_text(*self.check_ele)assert '确认订单' in res# 如果操作涉及页面跳转——需要返回对应的页面对象,如果没有,则不需要if __name__ == '__main__':# 首页——进入登录-首页-搜索商品-商品页面-商品详情页——认购页面-购物车页面from selenium import webdriverdriver = webdriver.Chrome()driver.implicitly_wait(10)IndexPage(driver).to_login().login('15**********','*********').search_item().pick_item().to_buy().add_cart().check_item()quit()
下面是一个UI流程测试的demo,分层更全面可以参考一下:https://blog.csdn.net/qq_37405087/article/details/117420481?spm=1001.2014.3001.5501