POM设计理念:
- 进入登录页,实现登录流程
- 进入商品详情页,实现商品下单流程
- 进入支付页,实现支付流程
POM将一个完整的业务流程,基于页面为单位,拆分成不同页面,不同子流程,通过小的子流程的拼接,实现完整的业务流程的自动化运行。所有的内容都是基于流程来进行设计的。不再是单纯基于操作步骤来完成。
POM只能够在UI自动化测试领域下使用。
## POM设计思路
POM的核心结构是四层(所有的测试框架都是逻辑代码与测试代码与测试数据全部需要分离),在不同公司层级可能会有增加,但是都是基于核心四个层级来的。
1. 基类BasePage:就是关键字驱动的底层逻辑类。用于做常用操作行为的封装,但是会于之前教的关键字驱动类有些许区别。
2. 页面对象类PageObject:是POM的核心层级。用于封装系统中各个不同的页面以及页面的相关内容
3. 测试用例类TestCases:是测试代码,用于编写测试用例。通过UnitTest或者Pytest都可以
4. 测试数据类型TestData:是测试数据,用于管理测试过程中的常用测试数据。
POM的结构设计,是非常遵循高内聚低耦合的形态。一般而言一个py文件就是一个独立的内容。
1、新建工程
2、base_page.py
'''
login_page页面对象的实现:
实现Fecmall的登录流程
所有的页面对象类,都遵循我的模板直接抄就行。
'''
from selenium import webdriver
from class23_pom import urls
from class23_pom.base_page.base_page import BasePage
# 登录页面对象:通过继承BasePage,来获取所有的元素操作行为
class LoginPage(BasePage):
# url:也不是每个页面的url都可以访问,根据实际需要进行增减
url = 'http://hcc.fecmall.com/customer/account/login'
# url = urls.LOGIN_URL # url汇总到一层
# 核心元素:包括定位方法与值。通过元组的形态将不同元素的信息进行区分管理
username = ('id', 'email')
password = ('id', 'pass')
button = ('id', 'js_registBtn')
# 业务流程:登录
def login(self, user, pwd):
# 访问login页面:通过self.url将url与页面对象进行绑定
self.open(self.url)
self.input(self.username, user)
self.input(self.password, pwd)
self.click(self.button)
# 调试
# if __name__ == '__main__':
# driver = webdriver.Chrome()
# lp = LoginPage(driver)
# lp.login('1234@qq.com', '123456')
3、page_object
1、login_page.py
'''
login_page页面对象的实现:
实现Fecmall的登录流程
所有的页面对象类,都遵循我的模板直接抄就行。
'''
from selenium import webdriver
from class23_pom import urls
from class23_pom.base_page.base_page import BasePage
# 登录页面对象:通过继承BasePage,来获取所有的元素操作行为
class LoginPage(BasePage):
# url:也不是每个页面的url都可以访问,根据实际需要进行增减
url = 'http://hcc.fecmall.com/customer/account/login'
# url = urls.LOGIN_URL # url汇总到一层
# 核心元素:包括定位方法与值。通过元组的形态将不同元素的信息进行区分管理
username = ('id', 'email')
password = ('id', 'pass')
button = ('id', 'js_registBtn')
# 业务流程:登录
def login(self, user, pwd):
# 访问login页面:通过self.url将url与页面对象进行绑定
self.open(self.url)
self.input(self.username, user)
self.input(self.password, pwd)
self.click(self.button)
# 调试
# if __name__ == '__main__':
# driver = webdriver.Chrome()
# lp = LoginPage(driver)
# lp.login('1234@qq.com', '123456')
4、test_cases
'''
实现UnitTest下的login操作行为
'''
import unittest
from ddt import ddt, data, unpack
from selenium import webdriver
from class23_POM.page_object.login_page import LoginPage
@ddt
class TestLogin(unittest.TestCase):
# 基于PO的登录操作行为
@data(['2375154305@qq.com', 'hcc123456'])
@unpack
def test_01_login(self, user, pwd):
lp = LoginPage(webdriver.Chrome())
lp.login(user, pwd)
if __name__ == '__main__':
unittest.main()
test_case_order.py
'''
测试用例调用pom:
1. 每一个测试用例执行前都会执行setup,所以,无法将driver对象共享到不同的测试用例之中,所以要用setupclass
2. 整个业务流程都是基于一个浏览器来实现,一方面满足用户的操作习惯,另一方面也可以提升自动化运行速度
3. 不同的子流程用不同的测试用例进行管理。会更加清晰与直观
4. 我这个只是个人习惯的设计方法,不代表是唯一的标准答案。
'''
import unittest
from ddt import ddt, file_data
from selenium import webdriver
@ddt
class TestDemo(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
driver = webdriver.Chrome(options=get_options())
cls.ip = IndexPage(driver)
cls.lp = LoginPage(driver)
cls.dp = DressPage(driver)
cls.ap = AddPage(driver)
cls.pp = PayPage(driver)
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
# 登录测试用例
@file_data('../test_data/test_order_login.yaml')
def test_01_login(self, **kwargs):
self.lp.login(kwargs['username'], kwargs['password'])
# 商品添加购物车
@file_data('../test_data/test_order_add.yaml')
def test_02_add(self, num):
self.dp.add_dress(num)
def test_03_add_pay(self):
self.ap.add_pay()
def test_04_pay(self):
self.pp.pay_order()
def test_05_logout(self):
self.ip.logout()
# 调试代码
if __name__ == '__main__':
unittest.main()
5、shopping.yaml
-
user: 2375154305@qq.com
pwd: hcc123456
num: 5