1、pytest可以识别执行的测试文件包括

test_*.py
_test.py
都可以识别该文件
测试用例识别:Test
类包含的所有test_*的方法(测试类不能带有__init__方法);不在class中的所有的test_*方法都可以识别

2、安装直接使用pip install -U pytest命令安装即可

3、pytest -k可以指定匹配运行某个测试测试用例,后面再加上-v可以查看某个测试用例的详细执行结果
pytest --collect-only 只收集测试用例
pytest -m mark 标签名 标记

我们看到有一个warning,产生的原因是这些标签不是可以识别的,那么我们怎么处理这个warning呢,我们可以创建一个pytest.ini文件进行注册这个标签,自定义标签名,内容如下
[pytest]
markers = case1

我们再次运行试下发现warning没有了

pytest.ini配置文件是pytest的主配置文件,一般放在项目工程的根目录,它可以指定pytest的运行方式,并且不能使用任何的中文符号
测试用例模块test_a.py:

class Test_A():def test_case_a(self):print(f"测试用例A")assert 6 > 5def test_case_b(self):print(f"测试用例B")assert 9 > 7

测试用例模块check_b.py:

class Check_B():def aaa_case_a(self):print(f"测试用例A---")assert 6 > 5def aaa_case_b(self):print(f"测试用例B---")assert 9 > 7

我们新建一个pytest.ini文件,来指定运行check开头的测试用例和模块
[pytest]
python_files = check_*
python_classes = Check_*
python_functions = aaa_*

运行pytest -v -s

可以看出只收集到了两条测试用例,分别是check_b.py模块下的两条测试用例,符合我们的预期
因为在执行pytest的时候,会首先执行我们的配置文件pytest.ini文件,所以我们可以在配置文件里面配置我们想要运行的命令,假设我们增加addopts = -v -s --alluredir=./result,如下

我们直接运行pytest

我们也可以忽略某些文件夹,使用norecursedirs = 运行时忽略某些文件夹,后面写上要忽略的文件夹名称
pytest框架结构
模块级别(setup_module/teardown_module)全局的
函数级别(setup_function/teardown_function)只对函数用例生效,在类外面
类级(setup_class/teardown_class)只在类中前后运行一次
方法级(setup_method/teardown_method)开始于方法始末,在类里面
类里面的(setup/teardown)运行在调用方法的前后

4、参数化

使用@pytest.mark.parametrize进行参数化
@pytest.mark.parametrize(argnames, argvalues)
argnames:要参数化的变量,string(逗号分隔),list,tuple
argvalues:参数化的值, list,list[tuple]

import pytestdef inc(x):return x + 1@pytest.mark.parametrize('a,b',[(1,2),(5,6),(7,8),(9,10)])
def test_answer_01(a,b):assert inc(a) == b

运行结果:

yaml实现参数化
yaml实现list

list- 10- 20- 30

yaml实现字典

dictby:idlocator:nameaction:click

yaml进行嵌套一

-- by:id- locator:name- action:click

yaml进行嵌套二

companies:-id:1name:liliage:16-id:2name:youyouage:18

我们先安装yaml这个库

使用如下进行加载yaml内容

import pytest
import yamldef inc(x):return x + 1@pytest.mark.parametrize(("a","b"),yaml.safe_load(open("./data.yaml")))
def test_answer_01(a,b):assert inc(a) == b

数据文件:

-- 1- 2
-- 3- 4
-- 6- 7
-- 10- 11

运行结果:

5、场景一:假设测试用例在执行前需要登陆,那么我们可以在执行前调用登录的方法,前提是要定义一个登陆方法,并且使用fixture进行装饰,同时,在测试用例中,也能够接收登陆函数的返回

@pytest.fixture()
def login():print("要开始登陆了哈")username = "xiongda"return usernameclass Test_A:def test_answer_02(self,login):print(f"test_answer_02  login={login}")if __name__ == '__main__':pytest.main()

运行结果:

场景二:在与其他测试工程师一起合作的时候,公共的模块要在不同的文件中 可以使用conftest.py这个文件进行数据共享,它放在不同位置起着不同范围的共享作用;当前conftest这个文件的文件名是不能变化的。

conftest.py的作用域是:对当前同级目录下所有的文件及包下的所有测试文件,测试方法生效,如果同级目录下没有conftest.py,会找上级目录或者上上级目录 的conftest.py里的fixture方法。
我们新建一个conftest.py文件

内容如下:

import pytest@pytest.fixture()
def login():print("这个是公共的方法")return "公共方法"

test_a.py文件内容

class Test_A():def test_case01(self,login):print(f"测试用例1 {login}")def test_case02(self):print("测试用例2")def test_case03(self):print("测试用例3")def test_case04(self):print("测试用例4")

我们运行test_case01这个测试用例,发现也能运行成功

场景三:我们可以使用scope来控制setup和teardown的作用域和范围

修改conftest.py文件如下

import pytest@pytest.fixture(scope = "class")
def login():print("这个是公共的方法")yield "公共方法"  #yield激活fixture  teardown方法print("teardown")

运行整个test_a.py这个模块

注意:scope = "session"表示在整个目录中只执行一次
scope = "moudle"表示每一个模块也就是每个.py文件执行一次

场景四:不想让原有的测试方法有所改动,想让每一个测试用例都运行公共的方法,我们可以使用autouse

修改condtest.py文件如下:@pytest.fixture(autouse=True)

import pytest@pytest.fixture(autouse=True)
def login():print("这个是公共的方法")yield "公共方法"  #yield激活fixture  teardown方法print("teardown")
class Test_A():def test_case01(self, login):print(f"测试用例1 {login}")def test_case02(self):print(f"测试用例2")def test_case03(self):print(f"测试用例3")def test_case04(self):print("测试用例4")

我们可以看到每一个测试用例都用到了公共的方法

场景五:为了使数据更加灵活,一般数据都是通过参数进行传递的,我们可以通过fixture固定参数request传递

修改conftest.如下

import pytest@pytest.fixture(autouse=True, params=["user1", "user2", "user3"])
def login(request):print("这个是公共的方法")print(request.param)yield ["user", "name"]  #yield激活fixture  teardown方法print("teardown")
class Test_A():def test_case01(self):print(f"测试用例1")def test_case02(self):print(f"测试用例2")def test_case03(self):print(f"测试用例3")def test_case04(self):print("测试用例4")

运行结果:

我们可以看到每一个测试用例下面都使用了这几个参数,和参数化功能相差不多

场景六:fixture与参数化相结合,传入一个fixture方法,将数据传入到fixture方法中,fixture方法使用request参数来接收这组数据

conftest.py:

import pytest@pytest.fixture()
def login(request):print("这个是公共的方法")

test_a.py

import pytestclass Test_A():@pytest.mark.parametrize("login", [(1, 1), (3, 3), (5, 5)], indirect = True)def test_case01(self, login):print(f"测试用例1")

运行结果:

pytest实用的插件介绍

pip install pytest-ordering 控制用例的执行顺序

pytest的默认执行顺序是自上向下执行(注意pytest多个装饰器的时候可能会发生冲突),如果要调整顺序,我们可以使用@pytest.mark.run(order=1),如果不小心标记成了相同的顺序,测试用例就按照自上而下执行了
代码如下:

import pytestclass Test_A():@pytest.mark.run(order=3)def test_case01(self):print(f"测试用例1")assert 2 > 1@pytest.mark.run(order=2)def test_case02(self):print(f"测试用例2")assert 2 > 0@pytest.mark.run(order=1)def test_case03(self):print(f"测试用例3")assert 28 > 12

运行结果:

pip install pytest-dependency 控制用例的依赖关系

@pytest.mark.dependency(depends=[依赖的测试用例名称])
比如说测试用例C对测试用例A和测试用例B都有依赖关系,我们希望只有当测试用例A和测试用例B都执行通过后,才去执行C,否则跳过C

假设测试用例D也依赖与测试用例A
当测试用例A失败的时候,测试用例C和测试用例D都会直接跳过,如下:

import pytestclass Test_A():@pytest.mark.dependency()def test_case_a(self):print(f"测试用例A")assert 2 > 5@pytest.mark.dependency()def test_case_b(self):print(f"测试用例B")assert 2 > 0@pytest.mark.dependency(depends=['test_case_a', 'test_case_b'])def test_case_c(self):print(f"测试用例C")assert 28 > 12@pytest.mark.dependency(depends=['test_case_a'])def test_case_d(self):print(f"测试用例D")assert 28 > 12def test_case_e(self):print(f"测试用例E")assert 28 > 12

运行结果如下:

当测试用例A运行通过,测试用例B运行不通过的时候,测试用例C运行不会通过,测试用例D和测试用例E运行通过,如下:

import pytestclass Test_A():@pytest.mark.dependency()def test_case_a(self):print(f"测试用例A")assert 6 > 5@pytest.mark.dependency()def test_case_b(self):print(f"测试用例B")assert 2 > 7@pytest.mark.dependency(depends=['test_case_a', 'test_case_b'])def test_case_c(self):print(f"测试用例C")assert 28 > 12@pytest.mark.dependency(depends=['test_case_a'])def test_case_d(self):print(f"测试用例D")assert 28 > 12def test_case_e(self):print(f"测试用例E")assert 28 > 12

运行结果:

pip install pytest-xdist 分布式并发执行测试用例

测试用例一共有100条,一个执行1分钟,就需要100分钟,如果并行测试10个人一起执行时间就会缩短,这就是一种并行测试,分布式场景;
此方法的应用存在一定的原则,第一,就是用例之间是相互独立的,用例之间没有相互依赖关系,用例可以完全独立运行;第二,用例执行没有顺序,随机顺序都能正常执行;第三,每个测试用例都能重复运行,运行结果不会影响其他测试用例
此应用方式测试用例较多的时候测试效果明显,在执行过程中使用pytest -n 3命令进行执行
示例中的执行效果不明显

pip install pytest-rerunfailures 失败重跑

使用命令pytest test_a.py --reruns 5 --reruns-delay 1 -vs
可以看出失败的用例执行了5次

import pytestclass Test_A():@pytest.mark.parametrize("a, b", [(1, 2), (3, 3), (5, 5)])def test_case01(self, a, b):print(f"测试用例1")assert a == b


pip install pytest-assume 多重校验
一个方法中写了多条断言,通常第一条过不去,下面的就不执行了,我们希望第一条报错之后,后面的也能够正常运行
使用pytest.assume(),代码如下:

import pytestclass Test_A():def test_case01(self):print(f"测试用例1")pytest.assume(1 > 2)pytest.assume(1 < 1)

pip intall pytest-html 测试报告

使用命令pytest -v -s --html=report.html --self-contained-html

浏览器打开

测试数据驱动:

也就是我们可以把数据写入到一个yaml文件中进行测试
新建一个data,yaml文件,内容如下

测试用例代码如下:

import yaml
import pytestwith open("./data.yaml") as f:datas = yaml.safe_load(f)myids = datas.keys()mydatas = datas.values()class Test_A():@pytest.mark.parametrize("a, b", mydatas, ids=myids)def test_case_a(self, a, b):print("测试用例A")assert a > b

运行结果我们发现可以运行成功,如下

测试步骤驱动:

我们在进行自动化的时候需要定位元素,定位元素的时候我们会经常使用find_element方式,因此我们封装该方法到一个类里面,或者使之成为一个单独的方法,之后我们再进行元素定位的时候就可以调用这个方法进行元素定位,这个过程我们称之为测试步骤驱动,简单理解为我们basepage类里面封装的方法

pytest的高级用法

我们可以利用已有的hook函数来定义我们自己的插件,并把它放在conftest.py文件中作为自己的本地插件,实现我们想要的各种需求
hook函数地址:https://docs.pytest.org/en/latest/_modules/_pytest/hookspec.html

场景一:
pytest_collection_modifyitems收集上来的测试用例实现定制化功能,解决的问题是:自定义用例的顺序,解决编码问题以及自动添加标签

我们在conftest.py文件里面添加如下内容:

from typing import List
import pytestdef pytest_collection_modifyitems(session: "Session", config: "Config", items: List["Item"]
) -> None:print(items)items.reverse()

使用pytest -vs运行测试用例后:

对比之前的测试用例

我们使用数据化驱动的时候,yaml文件中如果含有中文,那么运行结果会显示乱码,也就是会显示这样:

为了正常能够显示中文,我们需要添加如下代码在conftest.py文件中
item.name = item.name.encode(‘utf-8’).decode(‘unicode-escape’)
item._nodeid = item.nodeid.encode(‘utf-8’).decode(‘unicode-escape’)
conftest.py代码:

from typing import List
import pytestdef pytest_collection_modifyitems(session: "Session", config: "Config", items: List["Item"]
) -> None:print(items)# items.reverse()for item in items:item.name = item.name.encode('utf-8').decode('unicode-escape')item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')

data.yaml文件内容:

整数:- 12- 11
float:- 0.68- 0.6

test_a.py:

import pytest
import yaml
import pytestwith open("./data.yaml", encoding='utf-8') as f:datas = yaml.safe_load(f)print(datas)myids = datas.keys()mydatas = datas.values()class Test_A():@pytest.mark.parametrize("a, b", mydatas, ids=myids)def test_case_a(self, a, b):print("测试用例A")print(datas)assert a > b

运行之后显示了正常了:

当然也可以自动添加标签,然后可以运行某个对应的标签的代码
修改conftest.py代码
if ‘case_a’ in item._nodeid:
item.add_marker(pytest.mark.case_a)
if ‘case_b’ in item._nodeid:
item.add_marker(pytest.mark.case_b)

from typing import List
import pytestdef pytest_collection_modifyitems(session: "Session", config: "Config", items: List["Item"]
) -> None:print(items)# items.reverse()for item in items:item.name = item.name.encode('utf-8').decode('unicode-escape')item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')  #_nodeid测试用例名称if 'case_a' in item._nodeid:item.add_marker(pytest.mark.case_a)if 'case_b' in item._nodeid:item.add_marker(pytest.mark.case_b)

test_a.py文件还是这样

import pytest
import yaml
import pytestwith open("./data.yaml", encoding='utf-8') as f:datas = yaml.safe_load(f)print(datas)myids = datas.keys()mydatas = datas.values()class Test_A():@pytest.mark.parametrize("a, b", mydatas, ids=myids)def test_case_a(self, a, b):print("测试用例A")assert a > bdef test_case_b(self):print(f"测试用例B")assert 9 > 7

使用命令pytest test_a.py -m “case_b” -vs只运行case_b标签的测试用例

我们在运行测试用例的时候,也可以只运行我们上次运行失败的用例,使用参数
–lf, --last-failed 只重新运行上次运行失败的用例(或如果没有失败的话会全部跑)
–ff, --failed-first 运行所有测试,但首先运行上次运行失败的测试(这可能会重新测试,从而导致重复的fixture setup/teardown)

这里就不给大家举例子了

场景二:
我们可以使用pytest_addoption 自定义命令行参数,比如说我们需要在不同的环境中去运行我们的测试用例,那么我们就可以通过命令行去传递不同的环境标识,去得到我们想要的测试结果:

我们在conftest.py文件中编辑这些代码
def pytest_addoption(parser): #parser: 用户命令行参数与ini文件值的解析器
mygroup = parser.getgroup(“learn”) # group 将下面所有的 option都展示在这个group下。
mygroup.addoption("–env01", # 注册一个命令行选项
default=‘test’,
dest=‘env01’,
help=‘set your run env’
)
mygroup.addoption("–env02", # 注册一个命令行选项
default=‘test’,
dest=‘env02’,
help=‘set your run env’
)

#通过命令行来处理传递不同的参数,设置成fixture,将test环境和dev环境或者其他环境分别处理,获取想要的不同环境下的数据
@pytest.fixture(scope=‘session’)
def cmdoption(request):
myenv = request.config.getoption("–env", default=‘test’)
if myenv == ‘test’:
datapath = ‘datas/test/datas.yaml’

if myenv == 'dev':datapath = 'datas/dev/datas.yaml'with open(datapath) as f:datas = yaml.safe_load(f)
return myenv,datas
from typing import List
import pytest
import yamldef pytest_collection_modifyitems(session: "Session", config: "Config", items: List["Item"]
) -> None:print(items)# items.reverse()for item in items:item.name = item.name.encode('utf-8').decode('unicode-escape')item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')  #_nodeid测试用例名称if 'case_a' in item._nodeid:item.add_marker(pytest.mark.case_a)if 'case_b' in item._nodeid:item.add_marker(pytest.mark.case_b)def pytest_addoption(parser):   #parser: 用户命令行参数与ini文件值的解析器mygroup = parser.getgroup("learn")  # group 将下面所有的 option都展示在这个group下。mygroup.addoption("--env01",  # 注册一个命令行选项default='test',dest='env01',help='set your run env')mygroup.addoption("--env02",  # 注册一个命令行选项default='test',dest='env02',help='set your run env')#通过命令行来处理传递不同的参数,设置成fixture,将test环境和dev环境或者其他环境分别处理,获取想要的不同环境下的数据
@pytest.fixture(scope='session')
def cmdoption(request):myenv = request.config.getoption("--env", default='test')if myenv == 'test':datapath = 'datas/test/datas.yaml'if myenv == 'dev':datapath = 'datas/dev/datas.yaml'with open(datapath) as f:datas = yaml.safe_load(f)return myenv,datas

设置文件datas/test/datas.yaml内容如下:

test:ip: 192.168.21.20port: 3306

设置文件datas/dev/datas.yaml内容如下:

dev:ip: 10.20.2.1port: 3309

新建一个测试用例test_addoption.py:

def test_addoption(cmdoption):env, datas = cmdoptionprint(f"{env},{datas}")print(type(datas))ip = datas[env]['ip']print(ip)port = datas[env]['port']url = "http://"+str(ip)+":"+str(port)print(url)

我们使用pytest --help会发现在帮助文档中有我们自己设置的环境参数

之后我们使用命令pytest test_addoption.py --env02 test -vs运行该测试用例,发现能够正常运行

场景三:参数化简化
pytest_generate_tests可以实现自定义动态参数化方案或者扩展,也就是我们重写这个hook函数即可,说白了,只要我们用到了参数化,都可以考虑这个功能是否能够给我们带来一些方便

在conftest.py里面最后添加如下内容
def pytest_generate_tests(metafunc: “Metafunc”) -> None:
if “param” in metafunc.fixturenames:
metafunc.parametrize(“param”, metafunc.module.data_params, ids=metafunc.module.dataids, scope=‘function’)

from typing import List
import pytest
import yamldef pytest_collection_modifyitems(session: "Session", config: "Config", items: List["Item"]
) -> None:print(items)# items.reverse()for item in items:item.name = item.name.encode('utf-8').decode('unicode-escape')item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')  #_nodeid测试用例名称if 'case_a' in item._nodeid:item.add_marker(pytest.mark.case_a)if 'case_b' in item._nodeid:item.add_marker(pytest.mark.case_b)def pytest_addoption(parser):   #parser: 用户命令行参数与ini文件值的解析器mygroup = parser.getgroup("learn")  # group 将下面所有的 option都展示在这个group下。mygroup.addoption("--env01",  # 注册一个命令行选项default='test',dest='env01',help='set your run env')mygroup.addoption("--env02",  # 注册一个命令行选项default='test',dest='env02',help='set your run env')#通过命令行来处理传递不同的参数,设置成fixture,将test环境和dev环境或者其他环境分别处理,获取想要的不同环境下的数据
@pytest.fixture(scope='session')
def cmdoption(request):myenv = request.config.getoption("--env", default='test')if myenv == 'test':datapath = 'datas/test/datas.yaml'if myenv == 'dev':datapath = 'datas/dev/datas.yaml'with open(datapath) as f:datas = yaml.safe_load(f)return myenv,datas#
def pytest_generate_tests(metafunc: "Metafunc") -> None:if "param" in metafunc.fixturenames:metafunc.parametrize("param", metafunc.module.data_params, ids=metafunc.module.dataids, scope='function')

新建一个test_param.py文件,内容如下

import yamlwith open("./data_params.yaml") as f:data = yaml.safe_load(f)data_params = data.values()dataids = data.keys()def test_param(param):print(f"{param}")

新建一个./data_params.yaml文件,内容如下:

test1: [1, 2, 3]
test2: [4, 5, 6]
test3: [7, 8, 9]

我们运行这个test_param.py文件

这里我们需要注意的是:
测试用例里面的参数名要和conftest.py文件中pytest_generate_tests方法中的param名字要一致,可以自定义这个名字,前后一致即可
conftest.py文件中pytest_generate_tests方法中的data_params和dataids要和测试用例中的data_params和dataids也要一致,就像我们这个例子中的conftest.py和test_param.py这两个文件一致即可

6、allure测试报告:

allure是一个轻量级灵活的支持多语言的测试报告工具,java语言开发,支持pytest, javascript, php, ruby等,也可以集成到jenkins,在pycharm中我们需要安装allure-pytest(或者pip install allure-pytest)
在测试执行期间收集结果
pytest [测试文件] -s -q --alluredir=./resullt/(–alluredir这个选项用于指定存储测试结果的路径)
查看报告
allure serve ./result/
常用的特性
@feature添加功能名称
@story添加子功能名称
@step添加步骤细节
@attach天机具体的文本信息(图片、视频、网页等)

import allure@allure.feature("加购模块")
class TestA():@allure.story("第一条用例")def test_case1(self):print("测试用例1")@allure.story("第二条用例")def test_case2(self):print("测试用例2")@allure.story("第三条用例")def test_case3(self):print("测试用例3")@allure.story("第四条用例")def test_case4(self):print("测试用例4")@allure.feature("结算模块")
class TestB():@allure.story("结算模块第一条用例")def test_case1(self):print("结算模块测试用例1")@allure.story("结算模块第二条用例")def test_case2(self):print("结算模块测试用例2")

只执行结算模块的测试用例
pytest test_a.py --allure-features=“结算模块” -vs

只执行结算模块第二条用例
pytest test_a.py --allure-stories=“结算模块第二条用例” -vs


我们在源代码里面添加测试步骤:

import allure@allure.feature("加购模块")
class TestA():@allure.story("第一条用例")def test_case1(self):with allure.step("步骤一:选择商品"):print("选择商品")with allure.step("步骤二:点击加入购物车"):print("点击加入购物车")print("测试用例1")@allure.story("第二条用例")def test_case2(self):print("测试用例2")@allure.story("第三条用例")def test_case3(self):print("测试用例3")@allure.story("第四条用例")def test_case4(self):print("测试用例4")@allure.feature("结算模块")
class TestB():@allure.story("结算模块第一条用例")def test_case1(self):print("结算模块测试用例1")@allure.story("结算模块第二条用例")def test_case2(self):print("结算模块测试用例2")

只运行架构模块
pytest test_a.py --allure-features=“加购模块” -vs


执行生成一个测试结果
pytest test_a.py --allure-features=“加购模块” -vs --alluredir=./result
这里记录了我们每一条测试用例的执行结果

使用allure serve ./result命令生成测试报告


在测试报告中加入一个测试用例的链接地址,这里我们使用https://www.baidu.com/为例
修改源码如下
test_link = “https://www.baidu.com/”
@allure.testcase(test_link, “加购模块第二条测试用例”)

import allure@allure.feature("加购模块")
class TestA():@allure.story("第一条用例")def test_case1(self):with allure.step("步骤一:选择商品"):print("选择商品")with allure.step("步骤二:点击加入购物车"):print("点击加入购物车")print("测试用例1")test_link = "https://www.baidu.com/"@allure.testcase(test_link, "加购模块第二条测试用例")def test_case2(self):print("测试用例2")@allure.story("第三条用例")def test_case3(self):print("测试用例3")@allure.story("第四条用例")def test_case4(self):print("测试用例4")

运行如下:
pytest test_a.py --allure-features=“加购模块” -vs --alluredir=./result1
allure serve ./result1


使用allure serve ./result1是直接唤起浏览器,生成一个测试报告,如果我们要在本地直接生成一个html文件呢,我们可以使用
allure generate ./result1

本地会生成一个allure-report文件

右键打开index.html,这个是我们想要的生成的测试报告文件

我们指定生成一个哪一个文件下面,假设我们指定生成report文件里面,使用命令
allure generate ./result1 -o report

按照重要性级别进行一定范围测试

级别:Trivial-不重要 Minor不太重要 Normal 正常问题 Critical严重 Blocker:阻塞
在方法函数和类上面加@allure.severity(allure.severity_level.TRIVIAL)
执行时 pytest -s -v 文件名 --allure-severities="normal,critical"

import allure
#@allure.feature("加购模块")
class TestA():@allure.severity(allure.severity_level.CRITICAL)def test_case1(self):with allure.step("步骤一:选择商品"):print("选择商品")with allure.step("步骤二:点击加入购物车"):print("点击加入购物车")print("测试用例1")@allure.severity(allure.severity_level.MINOR)def test_case2(self):print("测试用例2")@allure.severity(allure.severity_level.NORMAL)def test_case3(self):print("测试用例3")@allure.severity(allure.severity_level.BLOCKER)def test_case4(self):print("测试用例4")

执行结果:

我们希望不适用方法名命名我们的测试报告的标题,也就是如图所示的位置


修改代码如下@allure.title(“加购第一条用例”):

import allure
#@allure.feature("加购模块")
class TestA():@allure.title("加购第一条用例")def test_case1(self):with allure.step("步骤一:选择商品"):print("选择商品")with allure.step("步骤二:点击加入购物车"):print("点击加入购物车")print("测试用例1")@allure.severity(allure.severity_level.MINOR)def test_case2(self):print("测试用例2")@allure.severity(allure.severity_level.NORMAL)def test_case3(self):print("测试用例3")@allure.severity(allure.severity_level.BLOCKER)def test_case4(self):print("测试用例4")

使用pytest test_a.py --alluredir=./result3
生成测试结果

使用allure serve ./result3生成测试报告

添加文本,html代码块,截图和视频
代码修改如下

import allure
#@allure.feature("加购模块")
class TestA():@allure.title("加购第一条用例")def test_case1(self):allure.attach("这是一个纯文本", attachment_type=allure.attachment_type.TEXT)def test_case2(self):print("测试用例2")allure.attach("<body>这是一段htmlbody代码块</body>", "html网页", attachment_type=allure.attachment_type.HTML)def test_case3(self):print("测试用例3")allure.attach.file("E:\hewangtong\picture\\300-220.jpg", name = "这是图片", attachment_type=allure.attachment_type.JPG)def test_case4(self):print("测试用例4")allure.attach.file("E:\hewangtong\VIDEO\\《更完善的中后台微前端解决方案-qiankun》.mp4", name = "这是一个视频", attachment_type=allure.attachment_type.MP4)

使用pytest test_a.py --alluredir=./result4命令生成测试结果

使用allure serve ./result4命令生成测试报告

我们也可以本地起一个服务,方便其他同学访问到我们的测试报告
allure open -h 127.0.0.1 -p 8880 ./report/

浏览器里面输入地址http://127.0.0.1:8880/index.html即可访问对应的测试报告

小插曲:我们可以使用hamcrest进行断言范围,官网地址:http://hamcrest.org/,里面有各种语言的源代码链接,大家可以按需取用

超级详细的pytest测试和allure测试报告相关推荐

  1. pyhton使用pytest框架生成allure测试报告

    一.基础环境 window环境:windows10python环境:python3.7pycharm: pycharm2020java环境:jdk1.8.0_151/jre1.8.0_301(可以不是 ...

  2. pytest测试框架——allure报告

    文章目录 一.allure的介绍 二.allure的运行方式 三.allure报告的生成 方式一.在线报告.会直接打开默认浏览器展示当前报告 方式二.静态资源文件报告(带index.html.css. ...

  3. pytest测试框架+allure

    1.测试识别和运行 文件识别: 在给定的目录中,搜索所有test_.py或者_test.py文件 用例识别: Test*类包含的所有test_*的方法(测试类不能有__init__方法) 不在类中的所 ...

  4. 基于pytest框架实现allure测试报告生成之用例描述参数feature,story,title

    allure用例描述参数汇总: epic.feature.story.title之间是层级关系的:epic > feature(模块功能点描述) > story(用户场景或故事) > ...

  5. Web自动化之Pytest测试框架

    pytest是一个python的单元测试框架,可以用于自动化测试中. 用例规则 pytest命令执行测试时,如果我们不指定具体的文件,PyTest默认从当前路径及其所有子目录中搜索py源文件,所有名字 ...

  6. Pytest测试框架的基本使用和allure测试报告

    一.测试用例的识别与运行 目录识别 通过pytest.ini配置文件配置 如果未指定任何参数,则收集从testpaths(如已配置)或当前目录开始.另外,命令行参数可以在目录.文件名或节点ID的任何组 ...

  7. pytest测试实战pdf_Pytest+Allure美化测试报告

    今日推荐音乐:我最爱的霉霉 在学习pytest的时候,生成的html报告觉得实在不是很美观,查到资料有很多测试报告的第三方插件,不仅美观而且查看测试用例也很方便,那我们一起来学习下吧~ 0 1 参考案 ...

  8. Pytest测试框架(五):pytest + allure生成测试报告

    系列文章目录 Pytest测试框架(一):pytest安装及用例执行 Pytest测试框架(二):pytest 的setup/teardown方法 Pytest测试框架(三):pytest fixtu ...

  9. python测试用例管理_Python测试框架Pytest的常用插件测试报告

    原标题:Python测试框架Pytest的常用插件测试报告 一.pytest-html 生成 html 测试报告 要求:Python 3.6+ 安装:pip install pytest-html 文 ...

  10. Pytest框架集成Allure定制测试报告详解(一)

    Allure简介 Allure是一款非常轻量级并且非常灵活的开源测试报告生成框架. 它支持绝大多数测试框架, 例如TestNG.Pytest.JUint等.它简单易用,易于集成.下面就Pytest如何 ...

最新文章

  1. 别踩白块java程序代码_别踩白块源码
  2. linux界面设计论文,毕业设计(论文)-基于linux的云校园桌面虚拟化系统的设计与实现.doc...
  3. 移动端常见的不同苹果手机media query汇总
  4. DVWA系列之17 CSRF攻击介绍与实施
  5. 通过padding-bottom或者padding-top实现等比缩放响应式图片
  6. 我们如何在Python中创建多行注释?
  7. java quartz DateBuilder
  8. javascript 对象属性
  9. 软件下载地址900款正版
  10. HTML基础标签和基本CSS行内样式
  11. Android 项目必备(二十)-->NFC 的基本使用
  12. AXI总线学习-------从零开始详细学-------------连载(7)读写处理架构,burst介绍,burst细节定义(burst type burst address)
  13. 阳春三月来几个python基础吧
  14. 笔记本电脑外接显示器以后检测不到笔记本电脑原来的显示器,把hdmi拔出来了也没用
  15. TCP协议从入门到精通
  16. 面试题 10.11. 峰与谷-贪心-Java
  17. IDEA中maven项目右边Dependencies报错飘红
  18. 【转载】浅谈 flash 中的设计模式:模版
  19. CAD转图片,没有转换器CAD图纸转换成图片
  20. Mysql数据库高CPU问题定位和优化

热门文章

  1. java开发正则表达式
  2. Win11怎么设置鼠标箭头图案?Win11更换鼠标图案的方法
  3. 4pda.ru注册验证的解码算法
  4. CAD中如何插入图框?CAD插入图框方法教程
  5. 主要空间数据挖掘方法
  6. 短视频无水印解析源码
  7. 期货市场对农业的影响
  8. Cisco 防火墙 SSH配置
  9. android手机的屏幕录制在哪里,手机屏幕录制在哪里,安卓手机视频录制软件分享...
  10. 图像频率和图像频谱的概念