一、产品分析
二、测试用例分析
2.1、传统线性测试脚本
import sys
import os
from hogwartsCourse.webAuto.business.login import login
curPath = os.path.abspath(os.path.dirname(__file__))
print(os.path.dirname(__file__))
print(curPath)
sys.path.append(curPath)
import time
import allure
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from business_base import UIBase
class TestMgtGoodList(UIBase):
def setup_class(self):
self.driver.maximize_window()
self.driver.implicitly_wait(5)
login(self.driver)
self.driver.find_element(By.XPATH, '//*[text()="商品管理"]').click()
self.driver.find_element(By.XPATH, '//*[text()="商品列表"]').click()
def get_screenshot(self):
timestamp = int(time.time())
picture_path = f"./pictures/screenshot_{timestamp}.PNG"
self.driver.save_screenshot(picture_path)
allure.attach.file(picture_path, name="pictures", attachment_type=allure.attachment_type.PNG)
def test_add(self):
product_name = "IQ02"
self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
WebDriverWait(self.driver, 10).until(
expected_conditions.element_to_be_clickable(
(By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
)
)
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
self.action.scroll_to_element(ele)
self.action.scroll_by_amount(0, 20)
ele.click()
self.get_screenshot()
# 断言1:可以找到创建成功字样的元素证明创建成功
assert self.driver.find_element(By.XPATH, '//*[text()="创建成功"]')
# 断言2:在商品列表查找新增商品的名字,如果不为空,则断言成功
assert self.driver.find_elements(By.XPATH, f'//*[text()="{product_name}"]')
# 清理脏数据
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()
def test_update(self):
product_name = "IQ02"
# 构造测试数据
self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
WebDriverWait(self.driver, 10).until(
expected_conditions.element_to_be_clickable(
(By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
)
)
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
self.action.scroll_to_element(ele)
self.action.scroll_by_amount(0, 20)
ele.click()
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="编辑"]').click()
ele = self.driver.find_element(By.XPATH, '//*[text()="更新商品"]')
self.action.scroll_to_element(ele)
# self.action.scroll_by_amount(0, 20)
ele.click()
self.get_screenshot()
# 断言1:可以找到编辑成功字样的元素证明编辑成功
assert self.driver.find_element(By.XPATH, '//*[text()="编辑成功"]')
# 清理脏数据
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()
def test_find(self):
product_name = "IQ02"
# 构造测试数据
self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
WebDriverWait(self.driver, 10).until(
expected_conditions.element_to_be_clickable(
(By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
)
)
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
self.action.scroll_to_element(ele)
self.action.scroll_by_amount(0, 20)
ele.click()
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="查看"]').click()
self.get_screenshot()
# 断言1:可以找到【商品详情】字样的元素证明查看成功
assert self.driver.find_element(By.XPATH, '//*[text()="商品详情"]')
self.driver.refresh()
# 清理脏数据
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()
def test_delete(self):
product_name = "IQ02"
# 构造测试数据
self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
WebDriverWait(self.driver, 10).until(
expected_conditions.element_to_be_clickable(
(By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
)
)
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
self.action.scroll_to_element(ele)
self.action.scroll_by_amount(0, 20)
ele.click()
self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()
self.get_screenshot()
# 断言1:可以找到【删除成功】字样的元素证明【删除成功】
assert self.driver.find_element(By.XPATH, '//*[text()="删除成功"]')
# 断言2:在商品列表查找删除商品的名字,如果为空,则断言成功
assert not self.driver.find_elements(By.XPATH, f'//*[text()="{product_name}"]')
三、PageObjectModel简介
3.1、PO模式设计原则
- 不要暴露页面内部的元素给外部
- 不需要建模 UI 内的所有元素
- 要用公共方法代表 UI 所提供的功能
- 同样的行为不同的结果可以建模为不同的方法
- 方法应该返回其他的 PageObject ,或者返回用于断言的数据
- 不要在方法内加断言
四、编写POM测试脚本
PO模式改造
4.1、梳理测试用例
1、业务操作流程
class TestLitemall
# 测试用例
# 添加商品类型:
"""登录页面:用户登录"""
# 访问登录页
# 输入“用户名”
# 输入“密码”
# 点击“登录”按钮
# ==》首页
"""系统首页:进入商品类目"""
# 点击菜单“商场管理”
# 点击菜单“商品类目”
# ==》类目列表页面
"""类目列表页面:点击添加"""
# 点击“添加”按钮
# ==》创建类目页面
"""创建类目页面:创建类目"""
# 输入“类目名称”
# 点击“确定”按钮
# ==》类目列表页面
"""类目列表页面:获取操作结果"""
# 获取冒泡消息文本
# ==》返回消息文本
2、前置后置动作
class TestLitemall:
# 前置动作
def setup_class(self):
# 初始化开始页面
pass
# 后置动作
def teardown_class(self):
# 退出浏览器
pass
4.2、构造PO模型
1、 页面类和方法
- 创建页面类
- 定义页面方法
4.3、编写测试用例
1、链式调用
- 新增功能
# 演示代码,直接复制不可用
# Python版本代码
# 新增功能
def test_add_type(self):
# 链式调用
res = self.home\
.go_to_category()\
.click_add()\
.create_category()\
.get_res()
4.4、业务具体实现
1、封装BasePage
- 封装driver
- 封装selenium api
2、实现页面方法
def click_create(self):
# 1、点击添加按钮
logger.info("商品列表页面:点击创建按钮")
self.wait_until_clickable(self.__BTN_CREATE)
self.do_find(self.__BTN_CREATE).click()
# ==>>进入到添加商品页面
from hogwartsCourse.webAuto.web_auto_po.page_obj.good_create_page import GoodCreatePage
return GoodCreatePage(self.driver)
3、封装页面元素
__BTN_CREATE = (By.XPATH, '//*[@class="el-icon-edit"]')
__SUCCESS = (By.XPATH, '//*[text()="创建成功"]')
五、测试脚本的优化
- 测试断言
- 数据清理
- 参数化
- 添加日志
- 测试报告