webUI自动化(九)使用allure测试报告
一、代码优化
- 局部代码封装
def save_config_from_excel(excel_path,config_path):
"""保存excel信息到配置文件"""
excel_obj = openpyxl.load_workbook(excel_path)
config_sheet_value = excel_obj['配置项'].values
config_dict = dict()
for config_data in config_sheet_value:
if config_data[0] != "编号":
# 字典的key=value,将url01作为key,http://192.168.42.10/作为value
config_dict[config_data[1]] = config_data[2]
# 写入配置信息到config.yaml
yaml_dict_update(config_path, config_dict)
# 打印存储的值
print(config_dict)
print("保存配置文件成功")
#关闭excel对象
excel_obj.close()
- 优化setup_class
def setup_class(self):
"""前置的 数据初始化内容"""
#1 获取excel对象,得到数据
self.excel_obj = openpyxl.load_workbook(excel_path)
# 2 把配置文件读取并存入config.yaml
save_config_from_excel(excel_path, config_path)
# 3 实例化Base
self.b = Base(config_path)
# 4 实例化case运行器,用了excel_obj,base_obj等
self.cr = CaseRunner(self.excel_obj, self.b)
- 提取excel_path和config_path为全局变量
excel_path = "../data/data.xlsx"
config_path = "../config/config.yaml"
class Testcase():
def setup_class(self):
"""前置的 数据初始化内容"""
#1 获取excel对象,得到数据
self.excel_obj = openpyxl.load_workbook(excel_path)
# 2 把配置文件读取并存入config.yaml
save_config_from_excel(excel_path, config_path)
# 3 实例化Base
self.b = Base(config_path)
# 4 实例化case运行器,用了excel_obj,base_obj等
self.cr = CaseRunner(self.excel_obj, self.b)
def teardown_class(self):
# 退出浏览器和excel对象
self.b.wait({'txt': '5'})
self.excel_obj.close()
self.b.quit({})
@pytest.mark.parametrize('case_name', get_excel_column_value(openpyxl.load_workbook(excel_path),yaml_read(config_path)['case_suite'],3))
def test_bilibili(self, case_name):
self.cr.case_runner(case_name)
二、添加入口文件
import os
def main():
os.system("pytest")
if __name__ == '__main__':
main()
- 测试流程
①main.py
②找到test_bilibili_08.py
③找到test_bilibili用例
④使用了setup,teardown方法
⑤调用封装的工具类
三、allure报告
- 下载allure渲染器,自行查找下载方法
- 下载allure-pytest
pip install allure-pytest
- 使用allure,修改main.py
# -*- coding: utf-8 -*-
import os
def main():
#使用pytest执行用例
# os.system("pytest")
#运行测试用例
os.system('pytest --alluredir ./allure/allure_result/')
#生成测试报告
os.system('allure generate ./allure/allure_result/ -o ./allure/allure_report --clean')
#打开测试报告.html
os.system('allure open -h 127.0.0.1 -p 8080 ./allure/allure_report')
if __name__ == '__main__':
main()
四、完整代码
- 目录结构
- base目录
base_tools.py
from selenium import webdriver
from base.chrome_options import chrome_options
from selenium.webdriver.support.wait import WebDriverWait
import time
from base.yaml_tools import yaml_read
class Base:
def __init__(self,config_file_path):
self.config_dict = yaml_read(config_file_path)
options = chrome_options()
if self.config_dict['headless'] == 1:
options.add_argument("--headless")
self.driver = webdriver.Chrome(chrome_options=options)
self.driver.implicitly_wait(5) #隐式等待
# self.config_dict = yaml_read(config_file_path)
def open(self,data_dict):
"""打开网址"""
base_url = self.config_dict[data_dict['locate_by']]
url = data_dict['txt']
if not url:
url = ''
self.driver.get(base_url + url)
def locate(self,data_dict):
"""定位--显示等待的应用"""
try:
# ele = self.driver.find_element(ele_type, ele_value)
ele = WebDriverWait(self.driver,6,0.5).until(lambda s:s.find_element(data_dict['locate_by'], data_dict['locate_value'])) #显式等待
return ele
except:
print("定位失败")
raise
def input(self,data_dict):
"""输入"""
self.locate(data_dict).send_keys(data_dict['txt'])
# self.driver.find_element(ele_type,ele_value).send_keys(txt)
def click(self,data_dict):
"""点击"""
self.locate(data_dict).click()
# self.driver.find_element(ele_type,ele_value).click()
def max_windows(self,data_dict):
"""窗口最大化"""
self.driver.maximize_window()
def switch_to_iframe(self,data_dict):
"""切换到iframe"""
self.driver.switch_to.frame(data_dict['txt'])
def switch_to_windows(self,data_dict):
"""切换新窗口"""
windows = self.driver.window_handles
self.driver.switch_to.window(windows[int(data_dict['txt'])]) #指定切换哪一页面,-1为最新页面
def assert_locate(self,data_dict):
"""断言--通过某元素可以被定位到"""
assert self.locate(data_dict) is not None,"断言失败"
print("断言成功")
# @staticmethod
def wait(self,data_dict):
"""固定等待"""
time.sleep(int(data_dict['txt']))
def quit(self,data_dict):
"""退出浏览器"""
self.driver.quit()
case_runner.py
class CaseRunner:
def __init__(self,excel_obj,base_obj):
self.excel_obj = excel_obj
self.b = base_obj
def case_runner(self,sheet_name):
# 获取sheet页的值
sheet_obj = self.excel_obj[sheet_name] # 获取一个sheet页对象
values = sheet_obj.values # 获取sheet页的值
for value in values:
# for 循环 每一行解析为一行关键字代码,循环每一行并执行
data_dict = dict() # 定义一个字典,用一个字典来接收当前行的值
# print(value)
if value[0] != "编号" and int(value[1]) == 1:
data_dict['no'] = value[0]
data_dict['yes_no'] = value[1]
data_dict['step_name'] = value[2]
data_dict['kw'] = value[3]
data_dict['locate_by'] = value[4]
data_dict['locate_value'] = value[5]
data_dict['txt'] = value[6]
data_dict['note'] = value[7]
data_dict['except'] = value[8]
try:
# print(data_dict)
# 执行用例
# getattr是获取属性,self.b是对象,data_dict['kw']是属性名称(方法名),data_dict是参数
getattr(self.b, data_dict['kw'])(data_dict)
print(data_dict['step_name'], '执行成功!')
except Exception as e:
print(data_dict['step_name'], '执行失败!')
raise
chrome_options.py
from selenium import webdriver
def chrome_options():
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches',['enable-automation']) #去掉默认的自动化提示
options.add_argument('start-maximized') #窗口最大化
prefs = {"credentials_enable_service": False, "pofile.password_manager_enable": False}
options.add_experimental_option("prefs", prefs) #去掉密码管理弹窗
options.add_argument("--no-sandbox") #关闭沙盒模式
# options.add_argument("--headless") #无头模式,无界面运行
options.add_argument('--kiosk-printing') #弹出打印窗口时,自动按下打印按钮
return options
excel_tools.py
import openpyxl
from base.yaml_tools import yaml_dict_update
def get_excel_column_value(excel_obj,sheet_name,column_num):
"""获取sheet页列的值"""
sheet_obj = excel_obj[sheet_name]
values = sheet_obj.values
case_list = list()
for value in values:
if value[0] != '编号':
case_list.append(value[column_num])
# print(case_list)
return case_list
def save_config_from_excel(excel_path,config_path):
"""保存excel信息到配置文件"""
excel_obj = openpyxl.load_workbook(excel_path)
# config_path = "../config/config.yaml"
config_sheet_value = excel_obj['配置页'].values
config_dict = dict()
for config_data in config_sheet_value:
if config_data[0] != "编号":
# 字典的key=value,将url01作为key,http://192.168.42.10/作为value
config_dict[config_data[1]] = config_data[2]
# 写入配置信息到config.yaml
yaml_dict_update(config_path, config_dict)
# 打印存储的值
print(config_dict)
print("保存配置文件成功")
#关闭excel对象
excel_obj.close()
yaml_tools.py
import yaml
def yaml_read(file_path):
"""read"""
with open(file_path,'r',encoding='utf-8') as f:
x = yaml.load(f,Loader=yaml.FullLoader)
return x
def yaml_a_write(file_path,data):
"""追加写入"""
f = open(file_path,'a',encoding='utf-8')
yaml.dump(data,f,allow_unicode=True)
f.close()
def yaml_w_write(file_path,data):
"""覆盖写入"""
f = open(file_path,'w',encoding='gbk')
yaml.dump(data,f,allow_unicode=True)
f.close()
def yaml_dict_update(file_path,dict_data):
"""对yaml(only for dict)进行更新"""
try:
x = yaml_read(file_path)
if not x:
x = dict()
x.update(dict_data)
yaml_w_write(file_path,x)
except:
print(f'{file_path}<<<<<{dict_data}更新失败!!!')
raise
if __name__ == '__main__':
res = yaml_read(r"E:\pythonProject\ZrlogWebUI\config\config.yaml")
print(res)
- config目录
config.yaml,可读取写入
case_suite: case_suite_01
headless: 0
url01: http://192.168.42.10/
url_bilibili: https://www.bilibili.com/
url_taobao_login: https://login.taobao.com/
- testcase目录
测试用例脚本
import openpyxl
import pytest
import sys
import allure
from base.case_runner import CaseRunner
# sys.path.append('../')
from base.base_tools import Base
from base.yaml_tools import yaml_dict_update, yaml_read
from base.excel_tools import get_excel_column_value, save_config_from_excel
excel_path = "./data/data.xlsx"
config_path = "./config/config.yaml"
class Test:
def setup_class(self):
"""前置的 数据初始化内容"""
# 1 获取excel对象
self.excel_obj = openpyxl.load_workbook(excel_path)
# 2 配置文件存入config.yaml
save_config_from_excel(excel_path,config_path)
# 3 实例化base
self.b = Base(config_path) #属性
# 4 实例化case运行器,用了excel_obj,base_obj等
self.cr = CaseRunner(self.excel_obj,self.b)
def teardown_class(self):
"""后置条件 teardown开头 数据初始化内容"""
"""退出浏览器和excel对象"""
self.b.wait({'txt': '5'})
# self.excel_obj.close()
# self.b.quit({})
@allure.title("{case_name}")
# 参数化
@pytest.mark.parametrize('case_name', get_excel_column_value(openpyxl.load_workbook(excel_path),
yaml_read(config_path)['case_suite'],
2))
def test_01(self, case_name):
self.cr.case_runner(case_name)
# if __name__ == "__main__":
# pytest.main(['Zrlog_test_d_pytest_Excel.py'])
- 运行入口
# -*- coding: utf-8 -*-
import os
def main():
#使用pytest执行用例
# os.system("pytest")
#运行测试用例
os.system('pytest --alluredir ./allure/allure_result/')
#生成测试报告
os.system('allure generate ./allure/allure_result/ -o ./allure/allure_report --clean')
#打开测试报告.html
os.system('allure open -h 127.0.0.1 -p 8080 ./allure/allure_report')
if __name__ == '__main__':
main()
- data目录