上文我们刚刚学习了pytest基本详解,这篇文章将结合Allure,搭建自动可视化测试框架
T0 全文案例源码
python-pytest-allurehttps://gitee.com/nicckco/study-python/tree/master/python-pytest-allure
T1 关于Allure
Allure Report 是一种灵活的多语言测试报告工具,可向您展示已测试内容的详细表示,并从日常测试执行中提取最大程度的信息。
Allure Report 能够为多个 CI/CD 系统上跨 11 种编程语言的数十种测试工具构建统一的报告。
官网地址:Allure Report — Open-source HTML test automation report tool
官方文档:Allure Report Docs — Documentation Overview
T2 安装Allure
T2-1 下载并配置
首先保证你已安装java,且运行环境在jdk1.8及以上
Allure下载地址:https://github.com/allure-framework/allure2/releases
选择合适的版本,下载解压,并配置path环境变量,路径指引到allure的bin文件夹下
T2-2 校验
校验是否安装成功
allure --version
T2-3 安装allure-pytest
allure-pytest是python的一个第三方库。用于连接pytest和allure,使它们可以配合在一起使用。
allure-pytest基于pytest的原始执行结果生成适用于allure的json格式结果。该json格式结果可以用于后续适用allure生成html结果。
pip install allure-pytest
T3 项目搭建
创建一个全新的python项目,T3基本结构如下
* outputs文件夹是自动生成的报表,先不用管
T3.1 根目录
- 在项目根目录下面新建一个app.py, 作为项目的启动文件
# 使用pytest收集所有的测试用例并运行,输出allure报告
import pytest
import os
# 生成JSON数据,加上--clean-alluredir解决JSON文件生成冗余问题
pytest.main()
# 命令:pytest -v -s --alluredir=outputs/reports/allure --clean-alluredir
# 将JSON文件转换成HTML格式的测试报告(生成JSON文件路径:outputs/reports/allure; 生成HTML报告路径:outputs/reports/html)
os.system("allure generate outputs/reports/allure -o outputs/reports/html --clean")
# 命令:allure generate outputs/reports/allure -o outputs/reports/html --clean
# 打开测试报告
os.system("allure serve outputs/reports/allure")
# 命令:allure serve outputs/reports/allure
- 在项目根目录下面新建一个pytest.ini, 作为项目的配置文件
#配置pytest命令行运行参数
[pytest]
# 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
addopts=-vs --alluredir=outputs/reports/allure --clean-alluredir
testpaths=testdemos # 当前目录下的scripts文件夹 -可自定义
# 配置测试搜索的文件名称
# 当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件 -可自定义
python_files=test*.py
# 测试文件夹下,测试类名称-可自定义
python_classes=Test_*
# 测试类下,测试用例名称-可自定义
python_functions=test_*
T3.2 测试案例
上面的pytest.init已经定义了测试案例需要放在testdemos文件夹下面
- step1: 在项目根目录,新建testdemos文件夹
- step2:在testdemos文件夹下面,新建一个测试案例文件:test_case1.py
testcase1.py
import pytest
@pytest.mark.parametrize("name,age,sex", [('张三',22,'男孩')])
def test_one(name,age,sex):
print('我的名字叫%s,我今年%d岁了,我是一个%s' %(name,age,sex))
pass
@pytest.mark.parametrize("a,b", [(22,15),(20,24)])
def test_two(a,b):
assert a > b
T4 运行展示
运行app.py,项目启动后会自动打开allure视图页面
T5 allure语法
allure提供测试案例命名的功能,同时也能对相应的功能场景做出备注等等
T5.1 allure.feature 和 allure.epic
allure.epic 主题,对class 类进行分组管理,相当于总体的描述,
allure.feature 特性,修饰class类,对其进行描述,如class A ,classB
* 一般情况,story和title都是对class 类进行修饰
语法:
@allure.feature("类A)
class A():
- 这里,我们在testdemos文件夹下,新建test_case2.py
import pytest
import allure
@allure.epic('会员')
@allure.feature("会员中心")
class Test_MemberCenter():
def test_member(self):
pass
@allure.epic("会员")
@allure.story("会员数据")
class Test_MemberData():
def test_data(self):
pass
- 运行app.py,效果如下:(点击behaviors可以看到备注,注:在suites下面是看不到备注的)
这里我们可以看到
calss Test_MemberCenter: 已经被备注为'会员中心',且在'会员'结构下
class Test_MemberData: 已经被备注为'会员数据',且在'会员'结构下
- 结论:
- epic 是一级类目; feature则属于是二级类目,位于一级类目下
- feature修饰class 类,对其进行备注,epic则包含多个class
T5.2 allure.story 和 allure.title
allure.story 对测试案例进行分组管理,如:登录
allure.title 对测试案例进行命名备注,如:密码登录 ,手机号登陆
* 一般情况,story和title都是对测试案例进行修饰
语法:
@allure.story('故事1')
def test_case2(self):
pass
- 这里,我们在test_case2.py文件夹下进行修改
import pytest
import allure
@allure.epic('会员')
@allure.feature("会员中心")
class Test_MemberCenter():
@allure.story('登录')
@allure.title('密码登录')
def test_login_pwdLogin(self):
pass
@allure.story('登录')
@allure.title('手机号登录')
def test_login_mobileLogin(self):
pass
@allure.story('退出')
@allure.title('退出登录')
def test_out_login():
pass
@allure.epic("会员")
@allure.story("会员数据")
class Test_MemberData():
def test_data(self):
pass
- 运行app.py,效果如下:(点击behaviors可以看到)
- 结论:(epic - > feature -> story -> title )
- epic:主题,包含class类,属于一级栏目
- feature:位于epic下,包含story,属于二级栏目
- story :故事,包含title,属于三级栏目
- title : 篇章,位于story下,属于四级栏目
T5.3 allure.step
allure.step 步骤 ,放置于测试案例之外,用于备注测试案例操作流程
with allure.step 步骤,放置于测试案例之内,用于备注测试案例操作流程
语法:
with allure.step('第二步'):
pass
- 这里,我们在test_case2.py文件夹下进行修改
import pytest
import allure
@allure.epic('会员')
@allure.feature("会员中心")
class Test_MemberCenter():
@allure.story('登录')
@allure.title('密码登录')
def test_login_pwdLogin(self):
with allure.step('校验账户名'):
pass
with allure.step("校验密码"):
pass
with allure.step('登录成功'):
pass
pass
@allure.story('登录')
@allure.title('手机号登录')
def test_login_mobileLogin(self):
with allure.step('校验手机号'):
pass
with allure.step("校验密码"):
print("密码错误!")
assert 1 == 2
with allure.step('登录成功'):
pass
pass
@allure.story('退出')
@allure.title('退出登录')
@allure.step('退出步骤')
def test_out_login(self):
pass
@allure.epic("会员")
@allure.story("会员数据")
class Test_MemberData():
def test_data(self):
pass
- 运行app.py,效果如下:(点击behaviors可以看到)
T5.4 allure跳转链接
allure 提供 在测试报告中添加链接地址的方式
allure.link: 跳转链接
allure.issure:跳转链接,一般特指需求或BUG链接地址
allure.testcase: 跳转链接,一般特指测试案例的地址
这三者都是跳转链接,不过涵义不一样(当然你不关心这个涵义,其实都一样,没区别)
@allure.link("http://www.xxx.com", name="跳转xxx")
def test_link_baidu():
pass
- 这里,在testmodes文件夹下,我们新建test_case3.py文件,写入下列内容
import pytest
import allure
@allure.epic('链接')
@allure.feature('链接中心')
class Test_Link():
@allure.story("跳转链接")
@allure.title('跳转百度')
@allure.link("https://www.baidu.com/", name="百度URL")
def test_link_go_baidu(self):
pass
@allure.story("跳转链接")
@allure.title('跳转阿里云')
@allure.issue("https://help.aliyun.com/zh/ecs/?spm=0.0.0.0/", name="阿里云帮助中心")
def test_link_issue_aliyun(self):
pass
@allure.story("跳转链接")
@allure.title('跳转京东')
@allure.testcase("https://jd.com/", name="跳转京东")
def test_link_testcase_jd(self):
pass
- 运行app.py,效果如下:(点击Links #阿里云帮助中心#会跳转到指定链接)
T5.5 allure标志安全级别
通常我们进行上线时测试,我们会对重要的功能进行测试,那么那些指定重要的功能,这里allure提供一种方法
语法:
@allure.severity(allure.severity_level.TRIVIAL)
def test_one():
pass
- allure.severity可以标记案例的安全级别:
- Trivial级别:不重要
- Minor级别:不太重要
- Normal级别:正常
- Critical级别:严重
- Blocker级别:阻塞
- 这里,在testmodes文件夹下,我们新建test_case4.py文件,写入下列内容
import pytest
import allure
@allure.epic('安全')
@allure.feature('安全中心')
class Test_safe():
@allure.story("安全级别")
@allure.title('Trivial:不重要')
@allure.severity(allure.severity_level.TRIVIAL)
def test_safe_trivial(self):
pass
@allure.story("安全级别")
@allure.title('Minor:不太重要')
@allure.severity(allure.severity_level.MINOR)
def test_safe_Minor(self):
pass
@allure.story("安全级别")
@allure.title('Normal:正常')
@allure.severity(allure.severity_level.NORMAL)
def test_safe_Normal(self):
pass
@allure.story("安全级别")
@allure.title('Critical:严重')
@allure.severity(allure.severity_level.CRITICAL)
def test_safe_Critical(self):
pass
@allure.story("安全级别")
@allure.title('Blocker:严重')
@allure.severity(allure.severity_level.BLOCKER)
def test_safe_Blocker(self):
pass
- 运行app.py,效果如下:
T5.6 allure.attach
allure.attach可以帮助你在测试报告中,添加文本,文件,代码
语法:
allure.attach("纯文本", attachment_type=allure.attachment_type.TEXT)
- 这里,在testmodes文件夹下,我们新建test_case5.py文件,写入下列内容
import pytest
import allure
@allure.epic('附加')
@allure.feature('附加中心')
class Test_Catch():
@allure.title('附加文本')
def test_attach_text(self):
allure.attach("纯文本", attachment_type=allure.attachment_type.TEXT)
@allure.title('附加html')
def test_attach_html(self):
allure.attach("<body>这是一段htmlbody块</body>", "html页面", attachment_type=allure.attachment_type.HTML)
@allure.title('附加图片')
def test_attach_photo(self):
allure.attach.file("files/catch.jpg", name="图片", attachment_type=allure.attachment_type.JPG)
- 运行app.py,效果如下:
T6 allure集成selenium
如果你想在你的测试报告中引入web自动化工具,可以在allure中引入selenium
T6.1 安装selenium
如果之前未安装selenium,使用下列命令安装:
pip install selenium
T6.2 引入selenium
- 这里,在testmodes文件夹下,我们新建test_case6.py文件,写入下列内容
import allure
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
@allure.epic('selenium')
@allure.feature('web中心')
class Test_Web():
@allure.title("效果展示")
def test_steps_demo(self):
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 程序会找到搜索框,然后自动输入allure文本
driver.find_element(By.ID,"kw").send_keys('allure')
# 程序自动点击搜索按钮
driver.find_element(By.ID,"su").click()
# 等待三秒钟,等查询出结果后再截图保存
time.sleep(3)
driver.save_screenshot("./files/catch2.png")
allure.attach.file("./files/catch2.png", attachment_type=allure.attachment_type.PNG)
allure.attach('<head></head><body>首页</body>', 'Attach with HTML type', allure.attachment_type.HTML)
- 运行app.py,效果如下:
注:这个案例会有几秒等待,中间不需要做任何操作,不要操作打开的chrome,所有操作由存续自动运行,直到测试报告生成为止