Pytest框架
介绍
1.简介
pytest是纯python编写的自动化测试框架,可以支持python语法编写测试用例,是一个非常成熟的全功能的Python测试框架。
主要有以下几个特点:
- 简单灵活,容易上手;
- 支持参数化;
- 能够支持简单的单元测试和复杂的功能测试,还可以结合selenium、requests做自动化测试;
- pytest具有很多第三方插件,并且可以自定义扩展。
安装:pip install pytest
2.第一个pytest用例
def test_01():
assert 1 == 1
3.pytest命名规范
-
测试模块:以
test_
开头命名,如:test_login.py
,或以_test
结尾; -
测试类:必须以
Test
开头命名,且测试类中不能有__init__
方法; -
测试方法/测试函数:必须以
test
开头。
4.常用参数
可以通过pytest -h来查看所有可用参数。pytest的参数有很多,下面是归纳一些常用的参数:
无参数:读取路径下符合条件的所有类、函数、方法全部执行;
-v:打印详细运行日志;
-s:输出调试信息,包括print打印的信息;命令行输入:pytest -s;
-x:运行用例失败立即停止运行
–maxfail
用例失败数达到某个设定的值停止运行
pytest --maxfail=[num]
-m 运行所有@pytest.mark.[标记名] 标记的用例比如:用例标记 @pytest.mark.high
pytest -m=hign 或者 pytest -m hign。# 表示只执行有此标记hight的case。
pytest -m="hign or smoke" 或者 pytest -m "hign or smoke" # 表示两种标记都执行
–reruns=num:失败用例重跑num次。需要安装 pytest-rerunfailures 插件模块。-n参数,启用多线程或分布式运行测试用例。需要安装pip install pytest-xdist 插件模块。
命令行输入:pytest -vs -n=2-k: 指定运行某个或某些用例
pytest -k ‘类名’
pytest -k ‘方法名’
pytest -k ‘类名 and not 方法名’ # 运行类里所有方法,不包含某个方法
命令行输入:pytest -vs -k=01python程序运行pytest:
caseNameString = " or ".join(caseNameList) cmd = f"python -m pytest -k \"{caseNameString}\" --alluredir ./allure --clean-alluredir" os.system(cmd) -k的值支持中文的哟~
参数-n,启用多线程或分布式运行测试用例。需要安装pip install pytest-xdist 插件模块。
命令行输入:pytest -vs -n=2
5.实现数据驱动
Pytest 测试框架的数据驱动是由 pytest 自带的pytest.mark.parametrize()来实现的。
@pytest.mark.parametrize() 装饰器接收两个参数:
第一个参数以字符串的形式存在,它代表能被测试函数所能接受的参数,如果被测试函数有多个参数,则以逗号分隔;
第二个参数用于保存测试数据。如果只有一组数据,以列表的形式存在,如果有多组数据,以列表嵌套元组的形式存在(例如: [1,1]或者[(1,1), (2,2)])。
实例
class Test01:
@pytest.mark.parametrize('a,b,expect',[(1,1,1),(2,3,5)])
def test_001(self,a,b,expect):
print('测试a+b的结果')
assert a+b==expect
@pytest.mark.parametrize('c,d,expect', [(2, 4, 2), (9, 10, 1)])
def test_002(self,c,d,expect):
assert d-c==expect
if __name__ == '__main__':
pytest.main([__file__, '-k','test_001'])
6.pytest fixtures
6.1 fixture用途
- fixture主要用来做初始化环境以及测试结束后的数据清除。
- pytest fixture与setup,teardown功能一样,但比之更加灵活,完全可以代替setup,teardown。
6.2 fixture参数详解
@pytest.fixture(scope='function',params=None,autouse=False,ids=None,name=None)
yieldfixture装饰器,相当于setup,测试用例的前置
* scope: 有四个级别参数'function(默认)'、'class'、'module'、'session'。
* params:一个可选的参数列表,列表中每个数据都可以作为用例的输入。也就说有多少数据,就会形成多少用例。可以通过request.param来获取该次调用的参数。
* autouse:如果True,自动调用fixture功能。如果为False则需要调用fixture。
* ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成。
* name:fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块。
yield:这个关键字之后的代码相当于teardown,测试用例的后置。
6.3 fixture的作用范围
fixture里面有个scope参数可以控制fixture的作用范围:session>module>class>function
-function:每一个函数或方法都会调用
-class:每一个类调用一次,一个类中可以有多个方法
-module:每一个.py文件调用一次,该文件内又有多个function和class
-session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
6.4 调用fixture的三种方法
方式1:函数或类里直接传fixture的函数名称
@pytest.fixture()
def test_fixture(self):
print('\n用例开始执行fix1\n')
yield
print('\n用例执行结束fix1\n')
def test_a(self, test_fixture):
print('runing')
assert 1 == 1
执行结果:
方式2: 使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例(可以叠加使用多个装饰器)
@pytest.fixture()
def test_fixture(self):
print('\n用例开始执行fix1\n')
yield
print('\n用例执行结束fix1\n')
@pytest.fixture()
def test_fixture2(self):
print('\n用例开始执行fix2\n')
yield
print('\n用例执行结束fix2\n')
@pytest.mark.usefixtures('test_fixture')
@