框架目录
首先我们构建框架所需要文件目录
Action----关键字
image—截图
log—日志
report—测试报告
Test Data—测试数据
utils–辅助工具
需要安装的包,pytest、selenium、pytest-xlsx、allure(需要下载,pip install allure-pytest 只是下载了插件)
在Action包中创建一个elementAction.py文件,该文件将我们对页面元素的操作进行封装,在读取到excel中的关键字后将步骤格式化调用这些方法进行ui操作
import time
from selenium import webdriver
from Utils.Find_element import find_element
driver = None
# 打开浏览器
def open_browser(browser_name, *args):
global driver
driver = getattr(webdriver, browser_name)()
# 获取页面地址
def get_url(url_name, *args):
global driver
driver.get(url_name)
# 窗口最大化
def max_window(*args):
global driver
driver.maximize_window()
# 等待
def sleep(seconds, *args):
time.sleep(seconds)
# 切换窗口
def switch_frame(location_type, location_name, *args):
global driver
try:
i_frame = find_element(driver, location_type, location_name)
driver.switch_to.frame(i_frame)
except Exception as e:
print(e)
# 输入数据
def input_content(location_type, location_name, content, *args):
global driver
find_element(driver, location_type, location_name).send_keys(content)
# 点击操作
def click(location_type, location_name, *args):
global driver
find_element(driver, location_type, location_name).click()
# 断言
def assert_info(element, assert_type, except_value, *args):
global driver
print(getattr(driver, element))
try:
if assert_type == 'absolute':
assert except_value == getattr(driver, element)
elif assert_type == 'include':
assert except_value in getattr(driver, element)
except Exception as e:
# 截图
get_image()
raise
# # 断言提示消息
# def assert_msg(location_type, location_name, value, *args):
# global driver
# print(find_element(driver, location_type, location_name).getText())
# try:
# assert value in find_element(driver, location_type, location_name).getText()
# except Exception as e:
# # 截图
# get_image()
# raise
# 截图
def get_image():
global driver
#图片存放路径,后续改造
driver.get_screenshot_as_file("./image/err.png")
# 关闭浏览器
def close_browser(*args):
global driver
driver.quit()
在utils中新建Find_element.py用来定位ui元素所在位置
from selenium.webdriver.support.wait import WebDriverWait
# selenium读取页面元素的方法封装
def find_element(driver, find_type, find_key):
try:
# 显示等待WebDriverWait
element = WebDriverWait(driver, 3).until(lambda driver: driver.find_element(by=find_type, value=find_key))
return element
except Exception as e:
raise e
下面构建测试数据,在Test Data中创建一个以test_开头的xlsx文件。
标记列是执行操作时要读取的关键字必须与elementAction.py中的方法名相同,其中name、mark是pytest-xlsx读取数据时所需信息用以创建测试用例,name表示用例名字,mark和pytest中的mark用法类似,指定用例标记,或使用数据驱动测试。
格式如下
在项目根目录创建conftest.py文件,构建测试用例。
import pytest
from pytest_xlsx.file import XlsxItem
# 关键字
from Action.elementAction import *
#自定夹具,
@pytest.fixture
def wd(): # 定义关键字
print("前置操作")
# 获取当前用例所在行
yield
# 关闭浏览器
print("后置操作")
close_browser()
@pytest.fixture
def wd1(): # 定义关键字
print("前置操作1")
yield
# 关闭浏览器
print("后置操作1")
close_browser()
'''
运行xlsx文件时执行的操作
'''
def pytest_xlsx_run_step(item: XlsxItem):
# 获取当前执行步骤
step = item.current_step
# 构建执行命令
method_express = ''
if step['值'] and step['操作方式'] is None and step['参数'] is None:
if isinstance(step['值'], int):
method_express = step['标记'] + "(" + str(step['值']) + ")"
else:
method_express = step['标记'] + "('" + step['值'] + "')"
# 只有关键字不为空
if step['操作方式'] is None and step['参数'] is None and step['值'] is None:
method_express = step['标记'] + "(" + ")"
# 只有操作值为空
if step['值'] is None and step['参数'] and step['操作方式']:
method_express = step['标记'] + "('" + step['操作方式'] + "'" + "," + "'" + step['参数'] + "')"
# 都不为空
if step['值'] and step['操作方式'] and step['参数']:
if isinstance(step['值'], int):
method_express = step['标记'] + "('" + step['操作方式'] + "'" + "," + "'" + step['参数'] + "'" + "," + str(
step['值']) + ")"
else:
method_express = step['标记'] + "('" + step['操作方式'] + "'" + "," + "'" + step['参数'] + "'" + "," + "'" + \
step['值'] + "')"
eval(method_express)
#单个步骤运行结果输出,不写不会影响运行。
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
# print('------------------------------------')
# # 获取钩子方法的调用结果
out = yield
# print('用例执行结果', out)
# # 从钩子方法的调用结果中获取测试报告
report = out.get_result()
if report.when == 'call':
# print('测试报告:%s' % report)
# print('步骤:%s' % report.when)
# print('用例编号:%s' % report.nodeid)
# print('用例描述:%s' % str(item.function.__doc__))
print(('运行结果: %s' % report.outcome))
# return report.outcome
然后我们就可以执行测试啦。
打开终端,确定路径在项目根目录,输入pytest -v 或 pytest -vs(查看详细信息)
pytest -v
pytest -vs
如果测试用例未通过,控制台中会显示错误位置
框架主题功能就已经搭建完成了,下面再完善一下。
增加运行日志,在根目录创建pytest,ini文件
[pytest]
#allure,其中report是存放allure文件的目录,clean是存放之前进行清除
addopts = --alluredir=report --clean-alluredir
#日志存放路径,目前是覆盖写入,追加写入还没有研究。
log_file = log/pytest.log
#日志级别 info以上才会写入
log_file_level=info
log_file_format= %(asctime)s %(levelname)s %(message)s
#日志时间
log_file_date_format = %Y-%m-%d %H:%M:%S
日志就完成啦
allure部分
日志中增加的addopts = --alluredir=report --clean-alluredir 在用例运行后会在目标目录创建一堆json文件。
opts = --alluredir=report --clean-alluredir 在用例运行后会在目标目录创建一堆json文件。
此时我们还不能直观的看到测试报告,在终端我们运行allure serve report 会自动打开html页面。
后续学习如何将详细信息和错误截图追加到测试报告中后更新