全称:page object model 页面对象模型
是自动化测试框架中的一个组成部分,把项目中的所有需要自动化测试的页面封装到类里面:一个页面对应一个类。 一个类就是一个模型。通过模型生成页面对象。相比较传统的记流水账式的线性脚本,它把web ui对象仓库从测试脚本分离,业务代码和测试脚本分离,将每一个页面都封装起来形成类,模块之间进行调用,提高了代码的复用性,也利于解决前端中UI变化频繁,测试后期代码的维护
POM分三层:
1、BagePage基础页面层:封装一些最基本的Selenium的原生的方法,提取每个页面的相同属性和方法,如定位元素,跳转框架,处理下拉框
2、PO页面层:页面对象层,继承BagePage基础页面层,把一个一个的页面封装成一个一个的类
3、测试用例层:测试用例的业务逻辑以及数据驱动
第二层PO层继承第一层BagePage基础层,第三层测试用例层调用第二层里面的方法
简单example1:
base_page.py 创建第一层BasePage层,封装基本的selenium元素定位
# 作者:yaxin.liang
# 日期:2022/4/13 19:29
# python版本:3.0
from selenium import webdriver
# 第一层:BasePage层
class BasePage:
# 构造方法:在生成对象时自动调用的方法
def __init__(self):
# 打开谷歌浏览器
self.driver = webdriver.Chrome();
# 加载项目地址
self.driver.get("http://www.baidu.com");
# 封装定位元素(所有的定位全部走这里) 八大定位元素:id、name、class_name、xpath、css_selector、tag_name、link_text、partial_link_text
def locator_ele(self,args):
ele = self.driver.find_element(*args);
return ele
baidu_page.py 创建第二层BaiduPage层,继承第一层,实现页面元素定位封装和执行协作方法
# 作者:yaxin.liang
# 日期:2022/4/13 19:39
# python版本:3.0
from selenium.webdriver.common.by import By
from oneDay.base.base_page import BasePage
# 第二层:po页面层
class BaiduPage(BasePage):
# 页面元素定位(类属性)
baidu_text_loc = (By.ID,"kw");
baidu_submit_loc = (By.ID,"su");
# 页面元素对象
def get_text_obj(self):
ele = self.locator_ele(BaiduPage.baidu_text_loc);
return ele;
def get_submit_obj(self):
ele = self.locator_ele(BaiduPage.baidu_submit_loc);
return ele;
# 页面协作
def search(self):
self.get_text_obj().send_keys("越努力越幸福!");
self.get_submit_obj().click();
test_baidu.py 创建第三层用例实现层,执行测试用例
# 作者:yaxin.liang
# 日期:2022/4/13 19:48
# python版本:3.0
import unittest
import time
from oneDay.po.baidu_page import BaiduPage
class TestBaidu(unittest.TestCase):
# 测试用例之前的准备工作
def setUp(self) -> None:
pass
def test01_baidu_searvh(self):
BaiduPage().search();
# 测试用例的扫尾工作
def tearDown(self) -> None:
time.sleep(3);
pass
if __name__ == "__main__":
unittest.main();
简单example2:
base_Page.py
# 作者:yaxin.liang
# 日期:2022/4/13 20:49
# python版本:3.0
from selenium import webdriver
class Tools:
# driver = webdriver.Chrome();
# 初始化浏览器
def __init__(self,driver):
self.driver = driver
# 访问浏览器
def open(self,url):
self.driver.get(url);
# 元素定位 find_element(By.ID,"pwd") *解包元组
def locator(self,loc):
return self.driver.find_element(*loc);
# 输入 定位后才能输入
def input(self,loc,txt):
self.locator(loc).send_keys(txt);
# 转换frame
def switch_frame(self,frame):
self.driver.switch_to.frame(frame);
# 点击
def on_click(self,loc):
self.locator(loc).click();
# 关闭
def quit(self):
self.driver.quit();
loadDate.py
# 作者:yaxin.liang
# 日期:2022/4/13 20:49
# python版本:3.0
from selenium import webdriver
class Tools:
# driver = webdriver.Chrome();
# 初始化浏览器
def __init__(self,driver):
self.driver = driver
# 访问浏览器
def open(self,url):
self.driver.get(url);
# 元素定位 find_element(By.ID,"pwd") *解包元组
def locator(self,loc):
return self.driver.find_element(*loc);
# 输入 定位后才能输入
def input(self,loc,txt):
self.locator(loc).send_keys(txt);
# 转换frame
def switch_frame(self,frame):
self.driver.switch_to.frame(frame);
# 点击
def on_click(self,loc):
self.locator(loc).click();
# 关闭
def quit(self):
self.driver.quit();
loadDate.py
# 作者:yaxin.liang
# 日期:2022/4/14 9:44
# python版本:3.0
# 获得yaml文件数据
import yaml
def loadyaml(filename):
# 读取yaml文件
files = open(filename,'r',encoding='utf-8')
# 读取files里面的内容
data = yaml.load(files,Loader = yaml.FullLoader);
print(data)
login.yaml
-
username: "10063828"
pwd: "123456Aa"
login.py
# 作者:yaxin.liang
# 日期:2022/4/13 21:05
# python版本:3.0
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from twoDay.base.base_Page import Tools
# 八大定位元素:id、name、class_name、xpath、css_selector、tag_name、link_text、partial_link_text
class LoginPage(Tools):
# 页面地址
url = "http://beta.kktv8.com/?pageId=100&actionid=10001";
login_link_id = (By.XPATH,"/html/body/div[1]/div/div/div[1]/div/div/div[3]/div[2]/ul/div/ul/li[1]/a");
login_frame_local = (By.XPATH,"/html/body/div[5]/div/div/div/div/iframe")
login_zhanghao_local = (By.XPATH,"/html/body/div[1]/div[1]/div/div[2]/div[1]/input");
login_password_local = (By.XPATH,"/html/body/div[1]/div[1]/div/div[2]/div[2]/input");
login_click_local = (By.XPATH,"/html/body/div[1]/div[1]/div/a");
def get_login_page(self):
ele = self.on_click(LoginPage.login_link_id);
return ele;
def input_login_message(self,login_zhanghao_text,login_password_text):
self.input(LoginPage.login_zhanghao_local,login_zhanghao_text);
self.input(LoginPage.login_password_local,login_password_text);
def local_frame(self):
frame = self.locator();
def login(self,login_zhanghao_text,login_password_text):
self.open(self.url);
time.sleep(3);
self.get_login_page();
time.sleep(3);
frame = self.locator(self.login_frame_local);
self.switch_frame(frame);
self.input_login_message(login_zhanghao_text,login_password_text);
time.sleep(3)
self.on_click(LoginPage.login_click_local);
time.sleep(5)
if __name__ == "__main__":
driver = LoginPage(webdriver.Chrome());
driver.login("10063828","123456Aa");
test_case.py
# 作者:yaxin.liang
# 日期:2022/4/14 9:11
# python版本:3.0
import time
import unittest
from ddt import ddt,file_data
from selenium import webdriver
from twoDay.page.login import LoginPage
@ddt
class TestLogin(unittest.TestCase):
# 用例执行钱要做的事
@classmethod
def setUp(cls) -> None:
# 会启动一个chromedriver.exe进程
cls.driver = webdriver.Chrome();
cls.lp = LoginPage(cls.driver);
@file_data('../data/login.yaml')
def test_01(self,username,pwd):
self.lp.login(username,pwd);
time.sleep(3);
# 用例执行后要做的事
@classmethod
def tearDown(cls) -> None:
cls.driver.quit();
if __name__ == "__main__":
unittest.main();
test_case2.py
# 作者:yaxin.liang
# 日期:2022/4/14 9:40
# python版本:3.0
import time
import pytest
from selenium import webdriver
from twoDay.config.loadDate import loadyaml
from twoDay.page.login import LoginPage
class TestLogin():
# 用例执行前要做的事
def setUp_class(cls) -> None:
cls.driver = webdriver.Chrome();
cls.lp = LoginPage(cls.driver);
print('start setup_class...............')
@pytest.mark.parametrize('utxt',loadyaml('../data/login.yaml'))
# @pytest.mark.parametrize('utxt',[{'username': '10063828', 'pwd': '123456Aa'}])
def test_01(self,utxt):
self.lp.login(utxt['username'],utxt['pwd']);
time.sleep(3);
# 用例执行后要做的事
def tearDown_class(cls) -> None:
cls.driver.quit();
if __name__ == "__main__":
pytest.main(['-s','-v','test_case2.py']);
run.py
# 作者:yaxin.liang
# 日期:2022/4/14 13:00
# python版本:3.0
# 生成测试报告 pytest
# allure 测试报告
'''
环境准备:
1、安装allure_pytest pip install allure-pytest
2、下载commanline包 下载到指定位置 python下
3、配置环境变量 找到path: C:\python\python38\allure-2.13.5\bin
4、重启
'''
import os
import pytest
if __name__ == "__main__":
# 执行用例生成测试报告 测试数据 文件夹
pytest.main(['-s','-v','./test_case/test_case2.py','--alluredir','./allure-results']);
# 生成测试报告 测试数据
os.system('allure generate ./allure-results -o ./allure-reports')
框架 = pom+日志处理logging+全局配置文件ini.yaml文件+数据驱动+各种封装
自动化框架:
1、python
2、selenium的原生方法
3、unitest、pytest单元测试框架
4、htmltestrunner、allure测试报告
5、数据驱动:ddt(excel,yaml,mysql)或 pytest(paramaters)
6、关键字驱动:公共类封装,随机数封装,数据库连接封装,全局登录封装
7、全局配置文件ini.yaml文件
8、日志
9、断言
10、python的第三方库
11、git、github等版本控制工具
12、jenkins持续集成