Pytest
# Pytest
# 规范
python的第三方单元测试库,
可以自动识别模块和测试函数
支持非常丰富的断言assert
语句
使用要求
- 测试文件名必须以
test_
开头或以_test
结尾 - 测试类必须以
Test
开头 - 测试的函数名必须以
test_
开头 - 测试类不能使用
init
方法
# 使用断言
# test_use_assert.py
import pytest
def add(a, b):
return a + b
def test_equal():
assert 5 == add(1, 5)
if __name__ == '__main__':
pytest.main(['test_use_assert.py'])
# 使用参数化
import pytest
def add(a, b):
return a + b
# 1
@pytest.mark.parametrize(['x', 'y'], [(1,2), (1,4), (0,5)])
def test_add_1(x, y):
assert 5 == add(x, y)
# 2
t1 = [(3,1), (1,4), (3,2),(2,2)]
@pytest.mark.parametrize(['x', 'y'], t1)
def test_add_2(x,y):
assert 5 == add(x, y)
# https://blog.csdn.net/weixin_30649859/article/details/101725672?ydreferer=aHR0cHM6Ly9jbi5iaW5nLmNvbS8%3D
# 方式三:参数为列表中嵌套字典
datas_dict = [
{"a": 1, "b": 2, "c": 3},
{"a": 11, "b": 22, "c": 33},
{"a": 111, "b": 222, "c": 333},
]
@pytest.mark.parametrize("data", datas_dict)
def test_add03(data):
res = data["a"] + data["b"]
assert res == data["c"]
if __name__ == '__main__':
pytest.main(['test_parameter.py'])
# 执行顺序
import pytest
# 依次为 2->1->3->4
def test_02():
print(2)
def test_01():
print(1)
class TestCls:
def test_04(self):
print(4)
def test_03(self):
print(3)
if __name__ == '__main__':
pytest.main(['test_execution_order.py'])
@pytest.mark.run(order=1)
def test_01():
print(1)
@pytest.mark.run(order=1)
, 在函数1前加装饰器,可以让函数提前触发
# 前置 && 后置
import pytest
def setup_module():
print('前置模块')
def teardown_module():
print('后置模块')
def setup_function():
print('前置函数')
def teardown_function():
print('后置函数')
def test_01():
assert 1 == 1
def test_02():
assert 2 == 2
if __name__ == '__main__':
pytest.main(['pytest_beforeAndafter.py'])
setup_module
,teardown_module
,模块级别的前后置,只执行一次setup_function
,teardown_function
,函数级别的前后置,函数执行前后执行
# fixture
# 简单使用
import pytest
@pytest.fixture()
def first_fixture():
return 1
@pytest.fixture()
def second_fixture(first_fixture):
return '2' + str(first_fixture)
@pytest.fixture()
def third_fixture():
return 1, 2, 3
@pytest.fixture()
def fourth_fixture():
return '4'
def test_case1(first_fixture):
assert 1 == first_fixture
assert 2 == first_fixture
def test_case2(second_fixture):
assert second_fixture == '21'
assert second_fixture == 21
def test_case3(third_fixture):
assert (1, 2, 3) == third_fixture
def test_case4(third_fixture, fourth_fixture):
assert (1, 2, 3) == third_fixture
assert fourth_fixture == 4
if __name__ == '__main__':
pytest.main(['test_fixture_use.py'])
# conftest
# conftest.py
import pytest
@pytest.fixture()
def first_fixture():
print('first fixture')
return 'first'
@pytest.fixture()
def second_fixture(first_fixture):
print('second fixture')
return 'second plus ' + first_fixture
# pytest_fixture_conftest
def test_case1(first_fixture, second_fixture):
assert first_fixture == 1
assert second_fixture == 2
conftest
可以配置共享的fixture
, 用来添加用户token
# fixture作用域控制 && 自动执行
import pytest
@pytest.fixture(scope='session', autouse=True)
def session_fixture():
print('session scope')
@pytest.fixture(scope='module', autouse=True)
def module_fixture():
print('module scope')
@pytest.fixture(scope='class', autouse=True)
def class_fixture():
print('class scope')
@pytest.fixture(scope='function', autouse=True)
def func_fixture():
print('function scope')
# @pytest.fixture(scope='methods', autouse=True)
# def func_fixture():
# print('methods scope')
def test_case1():
print('case1')
def test_case2():
print('case2')
class Test_cls():
def test_case3(self):
print('case 3')
# fixture 参数
import pytest
test_data = [{
'case_name': '登录成功测试',
'username': 'admin',
'password': 'lv123'
},{
'case_name': '登录失败测试',
'username': 'admin',
'password': 'lv1234444'
},{
'case_name': '用户名为空',
'username': 'admin',
'password': 'lv1234444'
}]
@pytest.fixture(params=test_data)
def para_data(request):
# request 是 pytest 内置 fixture, 名称不能更改
return request.param
def test_case(para_data):
# print(para_data)
username = para_data.get('username')
print(username)
case_name = para_data.get('case_name')
print(case_name)
password = para_data.get('password')
print(password)
@pytest.fixture(params=test_data)
, 传递参数return request.param
, 返回的request
是 pytest 内置 fixture, 名称不能更改username = para_data.get('username')
, 取数据,{ 'case_name': '用户名为空',...,'password': 'lv1234444'}
# skip test
import pytest
# 无条件跳过
@pytest.mark.skip()
def test_case1():
print('test case1')
a = 1
# 条件满足时跳过
@pytest.mark.skipif(a>0, reason='if a > 0 pass')
def test_case2():
print('test case22')
b = 1
# 条件不满足时执行
@pytest.mark.skipif(b<0, reason='if a > 0 pass')
def test_case3():
print('test case3')
# allure
import pytest
def add(a,b):
return a+b
def test_case1():
assert 1 == add(1,1)
def test_case2():
assert 2 == add(1,1)
def test_case3():
assert 3 == add(1,2)
def test_case4():
assert 4 == add(3, 2)
def test_case5():
assert 5 == add(3, 2)
def test_case6():
assert 5 == add(4, 3)
if __name__ == '__main__':
pytest.main(['test_use_allure.py'])
pytest test_use_allure.py --alluredir ./res
, 生成allure
报告需要的数据allure generate ./res -o ./report_allure --clean
, 使用allure
生成报告,allure data_dir -o report_dir
,--clean
,覆盖之前的生成的报告allure open index.html
, 打开allure
生成的报告- 如果有报错,参考 (opens new window),需要安装插件
pip install allure-pytest