pytest是一个非官方的单元测试框架,需要先进行安装。所以pip一下
运行目录下的所有py文件:pytest
运行目录下某一个py文件:pytest test_01.py
运行目录下py文件中的某个类:pytest test_02.py::TestClass
运行目录下py文件中某个类的某个方法:pytest
test_02.py::TestClass::test_one
指定目录运行:pytest testpy
打印详细的日志信息
代码里面有 print 输出语句,想在运行结果中打印 print 输出
pytest -k '类名' //运行指定的类
pytest -k '方法名' //运行指定的方法
pytest -k '类名 and not 方法名' //运行类里的方法,不包含某个方法
遇到失败用例立即停止运行
用例失败个数达到阀值后停止运行
pytest --maxfail 2 test_02.py
只运行标记 @pytest.mark.[标记名]的方法和类
比如类名上添加:
@pytest.mark.oneone,
执行命令:pytest -m "oneone" test_02.py
如果有多个标记可以用 and 或 or 进行组合
获取执行最慢的一个:pytest --durations=1
只收集用例不执行,可用于统计用例数
1 import pytest
2
3 def setup_module():
4 print("
setup_module,只执行一次,当有多个测试类的时候使用")
5 def teardown_module():
6 print("
teardown_module,只执行一次,当有多个测试类的时候使用")
7
8
9 # setup_function teardown_function作用于类外的函数
10 def setup_function():
11 print("
setup_function")
12 def teardown_function():
13 print("
setup_function")
14
15 def test_cls_out():
16 print("类外的函数方法")
17
18
19 class TestPytest1:
20 def setup_class(self):
21 print("
setup_class1,只执行一次,当有多个测试方法的时候使用")
22 def teardown_class(self):
23 print("
teardown_class1,只执行一次,当有多个测试方法的时候使用")
24
25
26 def setup_method(self):
27 print("
setup_method1,每个测试方法都执行一次")
28 def teardown_method(self):
29 print("teardown_method1,每个测试方法都执行一次")
30
31
32 def setup(self):
33 print("setup")
34 def teardown(self):
35 print("teardown")
36
37
38 def test_three(self):
39 print("test_three,测试用例")
40
41 def test_four(self):
42 print("test_four,测试用例")
安装:pip install pytest-ordering
负数越小越先执行(-100,-18,-1)
正数越小越先执行(1,18,100)
1 import pytest
2
3
4 class Testpy:
5 @pytest.mark.run(order=1)
6 def test_one(self):
7 print(111)
8
9 @pytest.mark.run(order=18)
10 def test_two(self):
11 print(222)
12
13 @pytest.mark.run(order=100)
14 def test_three(self):
15 print(333)
安装:pip install pytest-xdist
多个CPU并行执行用例,如果参数为 auto 自动检测系统的 CPU 数目;如果参数为数字,则指定运行测试的处理器进程数。
pytest -n auto
pytest -n [num]
安装:pip install pytest-html
指定报告的存放路径
--html=./report/report.html
加这个参数生成的报告css不是独立的
--self-contained-html
assert a
assert a == b
assert a in b
assert not a
assert a != b (a <> b一般不再使用)
fixture 有一个参数 scope,通过 scope 可以控制 fixture 的作用范围,根据作用范围大小划分:session> module> class> function
具体作用范围如下:
function 函数或者方法级别都会被调用(默认)
class 类级别调用一次
module 模块级别调用一次
session 是多个文件调用一次(可以跨.py文件调用,每个.py文件就是module)
1、以参数的形式传入到方法里执行
1 import pytest
2
3 @pytest.fixture()
4 def login():
5 print("登录需要的操作步骤")
6
7 @pytest.fixture()
8 def operate():
9 print("用例的执行步骤")
10
11 @pytest.fixture()
12 def xiao():
13 print("1234567890")
14
15 # 需要在函数中传入函数名,函数上需要先标记上 @pytest.fixture()
16 def test_case1(login, operate, xiao):
17 print("test_case1,需要登录执行完毕")
2、fixture的两种引用方式
1 import pytest
2
3
4 @pytest.fixture()
5 def open():
6 print("打开浏览器")
7 yield
8
9 print("执行teardown !")
10 print("最后关闭浏览器")
11
12
13 # 方式一:装饰器方式引用
16 @pytest.mark.usefixtures("open")
17 def test_search1():
18 print("test_search1")
19 # raise NameError
20 pass
21
22
23 # 方式二:在函数中传入
26 def test_search2(open):
27 print("test_search2")
28 # raise NameError
29 pass
3、conftest.py应用
conftest.py等同于scope=session
pytest test_scope1.py test_scope2.py
相应代码见:
https://github.com/hanshoukai/pytest_fixture
fixture为function
fixture为class
fixture为module
fixture为session
4、自动执行fixture装饰下的函数
conftest.py中标记为:@pytest.fixture(autouse="true")
每个测试函数都会自动调用该前置函数
5、fixture传递参数
1 import pytest
2
3 @pytest.fixture(params=[1, 2, 3])
4 def params(request):
5 return request.param
6
7 def test_com(params):
8 print(f"测试数据:{params}")
9 assert params < 5
传一个参数
1 # 传一个参数
2 @pytest.mark.parametrize("user", ["13552977251", "13552554252"])
3 def test_user(user):
4 print(user)
传两个参数
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+5", 7), ("7*5", 35)])
如上 "test_input,expected" 可以修改为 列表或者元组 的形式
列表:@pytest.mark.parametrize(["test_input","expected"], [("3+5", 8), ("2+5", 7), ("7*5", 35)])
元组:@pytest.mark.parametrize(("test_input","expected"), [("3+5", 8), ("2+5", 7), ("7*5", 35)])
1 # 传两个参数
2 @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+5", 7), ("7*5", 35)])
3 def test_function(test_input, expected):
4 # eval可以将字符串转成3+5的表达方式
5 print(test_input, expected)
6 assert eval(test_input) == expected
传三个参数 三组数据,ids是别名必须与参数的数量保持一致
参数组合
1 # 参数组合
2 @pytest.mark.parametrize("x", [1, 2])
3 @pytest.mark.parametrize("y", [3, 4, 5])
4 def test_num(x, y):
5 # print(f"测试数据组合x: {x} , y:{y}")
6 print("测试数据组合x:"+str(x)+" y:"+str(y))
函数返回值类型
1 # 函数返回值类型
2 def return_data():
3 return [(1, 2), (3, 4)]
4
5 @pytest.mark.parametrize("a,b", return_data())
6 def test_data(a, b):
7 print(a)
8 print(b)
用yaml文件做为参数化的数据源
companyid.yaml
-
- 23725503
- 24721214
- 2352987806
data.yaml
-
- 20
- 30
-
- 40
- 50
脚本:
1 import pytest
2 import yaml
3
4
5 @pytest.mark.parametrize('a, b', yaml.safe_load(open("data.yaml", encoding='utf-8')))
6 # @allure.step("方法的描述信息")
7 def test_fo(a, b):
8 print(a)
9 print(b)
10
11
12 @pytest.mark.parametrize('company_id', yaml.safe_load(open("companyid.yaml", encoding='utf-8')))
13 # @allure.step("方法的描述信息")
14 def test_foo(company_id):
15 print("企业ID:", company_id)
1 [pytest]
2 # 空格分隔,可添加多个命令行参数 重试两次每隔5秒 生成报告
3 addopts = -sv --reruns 2 --reruns-delay 5 --html=./report/report.html --self-contained-html
4 #addopts = -s -v --alluredir=./result
5 # 当前目录下
6 testpaths = ./testcase/
7 #配置测试搜索的文件名称,当前目录下以test开头,以.py结尾的所有文件
8 python_files = test*.py
9 #配置测试搜索的测试类名,当前目录下以Test开头的所有类
10 python_classes = Test
11 #配置测试搜索的测试类名,当前目录下以test_开头的所有方法
12 python_functions = test_*
用例失败后自动重新运行:pytest-rerunfailures
使用方法:pytest test_x.py --reruns=2 --reruns-delay 5 #失败后重试2次,每次间隔5秒
在脚本中指定定义重跑的次数,这个时候在运行的时候,就无需加上 --reruns 这个参数
1 @pytest.mark.flaky(reruns=6, reruns_delay=2)
2 def test_example(self):
3 print(3)
留言与评论(共有 0 条评论) “” |