07.1 PO模式演练
2024年10月28日大约 4 分钟
07.1 PO模式演练
1. PO模式设计
- 结构
- base
- 存放所有Page页面公共方法
- page
- 将页面封装为对象
- script
- 测试脚本
- base
2. 登录
1. base
- 分析要实现页面公共方法
"""
Base类:存放所有Page页面公共操作方法!
"""
from selenium.webdriver.support.wait import WebDriverWait
class Base:
def __init__(self, driver: selenium.webdriver):
self.driver = driver
# 查找元素
# 输入方法
# 点击方法
# 获取文本值方法
base实现
import selenium from selenium.webdriver.support.wait import WebDriverWait class Base: """ Base类:存放所有Page页面公共操作方法! """ def __init__(self, driver: selenium.webdriver): """ 初始化 :param driver: """ # 驱动 self.driver = driver def base_find(self, loc: tuple, timeout=10, poll_frequency=0.5): """ 查找元素 :param loc: 元素定位 格式:(By.ID,"userA") :param timeout: 超时时长 :param poll_frequency: 查找频率 :return: 元素对象 """ # 显示等待 -> 查找元素 loc = (By.ID,"userA") *loc=loc[0], loc[1] return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll_frequency) \ .until(lambda d: d.find_element(*loc)) # 输入方法 def base_input(self, loc, value): """ 输入方法 :param loc: 元素定位 格式:(By.ID,"userA") :param value: 输入内容 :return: """ # 1、获取元素 el = self.base_find(loc) # 2、清空操作 el.clear() # 3、输入内容 el.send_keys(value) # 点击方法 def base_click(self, loc): """ 点击方法 :param loc:元素定位 格式:(By.ID,"userA") :return: """ self.base_find(loc).click() # 获取文本值方法 def base_get_text(self, loc) -> str: """ 获取文本值方法 :param loc: 元素定位 格式:(By.ID,"userA") :return: 元素文本 """ return self.base_find(loc).text
2. page
page结构搭建
""" 模块名:page_模块单词 类名:大驼峰将模块移植进来,去掉下划线和数字。 方法:自动化测试当前页面要操作那些元素,就封装那些方法 """ class PageLogin: # 输入用户名 def __page_username(self): pass # 输入密码 def __page_pwd(self): pass # 输入验证码 def __page_verify_code(self): pass # 点击登录按钮 def __page_click_login_btn(self): pass # 获取昵称 def page_get_nickname(self): pass # 组合业务方法 (强调:测试业务成调用此方法,便捷。) def page_login(self): pass
配置信息整理
from selenium.webdriver.common.by import By # 用户名 username = (By.CSS_SELECTOR, "#username") # 密码 pwd = By.CSS_SELECTOR, "#password" # 验证码 verify_code = By.CSS_SELECTOR, "#verify_code" # 登录按钮 login_btn = By.CSS_SELECTOR, ".J-login-submit" # 昵称 nick_name = By.CSS_SELECTOR, ".userinfo" # 提示:nick_name = By.CLASS_NAME, ".userinfo" == (By.CLASS_NAME,".userinfo")
page实现
""" 模块名:page_模块单词 类名:大驼峰将模块移植进来,去掉下划线和数字。 方法:自动化测试当前页面要操作那些元素,就封装那些方法 """ import selenium from selenium.webdriver.common.by import By from po.base.base import Base # 用户名 username = (By.CSS_SELECTOR, "#username") # 密码d pwd = (By.CSS_SELECTOR, "#password") # 验证码 verify_code = (By.CSS_SELECTOR, "#verify_code") # 登录按钮 login_btn = (By.CSS_SELECTOR, ".J-login-submit") # 昵称 nick_name = By.CSS_SELECTOR, ".userinfo" # 提示:nick_name = By.CLASS_NAME, ".userinfo" == (By.CLASS_NAME,".userinfo") class PageLogin(Base): """ 登录页面,页面操作 """ def __init__(self, driver: selenium.webdriver): # super().__init__(driver) # 驱动 self.driver = driver # 输入用户名 def __page_username(self, value): """ 输入用户名 :param value: 用户名 :return: """ self.base_input(username, value) # 输入密码 def __page_pwd(self, value): """ 输入密码 :param value: 密码 :return: """ self.base_input(pwd, value) # 输入验证码 def __page_verify_code(self, value): """ 输入验证码 :param value: :return: """ self.base_input(verify_code, value) # 点击登录按钮 def __page_click_login_btn(self): """ 点击登录按钮 :return: """ self.base_click(login_btn) # 获取昵称 def page_get_nickname(self): """ 获取昵称 :return: """ return self.base_get_text(nick_name) # 组合业务方法 (强调:测试业务成调用此方法,便捷。) def page_login(self, phone, password, code): """ 组合业务方法 (强调:测试业务成调用此方法,便捷。) :param phone: 手机号 :param password: 密码 :param code: 验证码 :return: """ self.__page_username(phone) self.__page_pwd(password) self.__page_verify_code(code) self.__page_click_login_btn()
3. scirpt实现
import unittest
from time import sleep
from parameterized import parameterized
from selenium import webdriver
from po.page.page_login import PageLogin
from po.util import read_json
class TestLogin(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get("http://192.168.10.31:9003/Home/user/login.html")
self.login = PageLogin(self.driver)
def tearDown(self) -> None:
sleep(3)
self.driver.quit()
def test01_login(self, phone="13800138006", password="123456", code="8888"):
# 调用登录业务
self.login.page_login(phone, password, code)
# 断言
nickname = self.login.page_get_nickname()
self.assertEqual(phone, nickname, '用户名匹配失败')
print("nickname:", nickname)
4. 数据驱动(parameterized)
1. 理论回顾
- 什么是数据驱动?
- 以测试数据驱动用例执行(测试数据和代码分离)
- 为什么要数据驱动?
- 便于维护(维护的焦点从代码转到测试数据)
- 数据驱动如何操作?
- 编写数据存储文件
- 编写读取数据工具
- 用参数化引用
2. 实际操作
步骤1、编写数据存储文件
口诀: 1、新建json文件,在文件中编写一个{} 2、有几个模块,写几个Key,值为列表 3、列表中参数化数据有几组,就写几个{} 3、每个{}中组成->说明+参数数据+预期结果
{ "login": [ { "desc": "登录成功", "phone": "13800138006", "password": "123456", "code": "8888", "expect_text": "王然啊啊啊啊啊啊" } ] }
步骤2、读取工具封装
import array import json import os # 读取json工具 def read_json(filename, key) -> array: """ 读取json工具 :param filename: 文件名称 :param key: 关键词 key :return: array """ filepath = os.path.dirname(__file__) + os.sep + "data" + os.sep + filename arr = [] with open(filepath, "r", encoding="utf-8") as f: for data in json.load(f).get(key): arr.append(tuple(data.values())[1:]) return arr if __name__ == '__main__': """ [(),()] """ print(read_json("login.json", "login"))
步骤3、参数化引用
import unittest from time import sleep from parameterized import parameterized from selenium import webdriver from po.page.page_login import PageLogin from po.util import read_json class TestLogin(unittest.TestCase): def setUp(self) -> None: self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.get("http://192.168.10.31:9003/Home/user/login.html") self.login = PageLogin(self.driver) def tearDown(self) -> None: sleep(3) self.driver.quit() # def test01_login(self, phone="13800138006", password="123456", code="8888"): # # 调用登录业务 # self.login.page_login(phone, password, code) # # 断言 # nickname = self.login.page_get_nickname() # self.assertEqual(phone, nickname, '用户名匹配失败') # print("nickname:", nickname) @parameterized.expand(read_json("login.json", "login")) def test02_login(self, phone, password, code, expect_text): print(phone, password, code, expect_text) try: # 调用登录业务 self.login.page_login(phone, password, code) # 断言 nickname = self.login.page_get_nickname() print("nickname:", nickname) self.assertEqual(nickname, expect_text, "昵称与预期结果不一致") except Exception as e: print("错误!", e)