pytest特点介绍
- 简单灵活,能适应很多场景;
- 支持参数化,可以细粒度地控制要测试的测试用例;
- 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium appnium等自动化测试、接口自动化测试(pytest+requests);
- pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)等;
- 可以集成到jenkins上做持续集成;
pytest编写规则
编写pytest测试样例非常简单,只需要按照下面的规则:
- 测试文件以test_开头(以_test结尾也可以)
- 测试类以Test开头,并且不能带有init方法
- 测试函数以test_开头
- 断言使用基本的assert即可
参数传递:
## - 列表[] : 字典 [{'uname':'guoliang', 'upas':'123456'}]
@pytest.mark.parametrize('udata', loadyaml('./data/login.yaml'))
def test_02(self, udata):
print(udata['uname'])
定义loadyaml:
def loadyaml(filename):
stream = open(filename, 'r')
# 读取文件数据
data = yaml.load(stream, yaml.FullLoader)
return data
pytest.mark.parametrize
Pytest中装饰器@pytest.mark.parametrize('参数名',list)可以实现测试用例参数化,类似DDT
如:
@pytest.mark.parametrize('请求方式,接口地址,传参,预期结果',[('get','www.baidu.com','{"page":1}','{"code":0,"msg":"成功"})',('post','www.baidu.com','{"page":2}','{"code":0,"msg":"成功"}')])
1、第一个参数是字符串,多个参数中间用逗号隔开
2、第二个参数是list,多组数据用元祖类型;传三个或更多参数也是这样传。list的每个元素都是一个元组,元组里的每个元素和按参数顺序一一对应
3、传一个参数 @pytest.mark.parametrize('参数名',list) 进行参数化
4、传两个参数@pytest.mark.parametrize('参数名1,参数名2',[(参数1_data[0], 参数2_data[0]),(参数1_data[1], 参数2_data[1])]) 进行参数化
import pytest
def return_data():
return [(1,2),(3,4)]
# 使用函数返回值的形式传入参数值
@pytest.mark.parametrize("a,b", return_data())
def test_01(a,b):
print("\n" + "a=%d, b=%d" % (a,b))
if __name__ == '__main__':
pytest.main(['-s', 'test_return.py'])
fixture之params参数可以实现参数化:(可以为list,tuple,或者字典列表、字典元组等)
pytest.ini:可以修改 pytest 的默认行为
注意: pytest.ini 不能使用任何中文符号,包括汉字、空格、引号、冒号等等;
更改默认命令行参数:
将常用的命令行参数设置为默认,省去重复输入的工作;
# pytest.ini
[pytest]
addopts = -rsxX -l -strict --tb=short
注册 mark 标记:
# pytest.ini
[pytest]
markers =
demo : marks tests as demo
smoke: marks tests as smoke
test : marks tests as test
控制台实时输出日志:
# pytest.ini
[pytest]
log_cli = 1
指定 pytest 最低版本号:
# pytest.ini
[pytest]
minversion = 3.0
指定 pytest 忽略某些目录:
pytest 收集测试用例时,会递归遍历所有子目录,包括某些你明知道没必要遍历的目录,遇到这种情况,可以使用 norecursedirs 参数简化 pytest 的搜索工作;norecursedirs 默认的设置是:.* build dist CVS _darcs {arch} *.egg ,多个路径用空格隔开。
# pytest.ini
[pytest]
norecursedirs = .* build dist CVS _darcs {arch} *.egg venv src
指定测试目录:
testpaths 限定测试用例的搜索范围,只有在 pytest 范围指定文件目录参数或测试用例标识符时,该选项才会启用;
testpaths 指定的路径是以 testpaths 所在的目录为基准的相对路径;
# pytest.ini
[pytest]
testpaths = test_path
更改测试用例收集规则:
pytest 默认的用例收集规则:
测试模块必须以 test_ 开头或以 _test 结尾;
测试类必须以 Test 开头,且不能有 __init__() ;
测试方法必须以 test_ 开头;
下面我们来添加自己的收集规则:
添加 check_ 开头的测试模块;
添加 Check 开头的测试类;
添加 check_ 开头的测试方法;
# pytest.ini
[pytest]
python_files = test_* *_test check_*
python_classes = Test* Check*
python_functions = test_* check_*
禁用 XPASS:
将标记为 @pytest.mark.xfail 但实际通过的测试用例报告为失败;
# pytest.ini
[pytest]
xfail_strict = true
避免文件名冲突:
为所有的测试目录添加 __init__.py,当多个测试目录拥有重名文件时,__init__.py 可以避免文件名冲突;
动态添加及获取 ini 配置参数:
# conftest.py
import pytest
def pytest_addoption(parser):
parser.addini('nice', type='bool', default=True, help='添加 ini 参数')
@pytest.fixture(autouse=True)
def get_ini(pytestconfig):
"""获取 ini 参数"""
nice = pytestconfig.getini('nice')
print(nice)