Pytest
- [pytest 基础使用](#pytest 基础使用)
-
- pytest安装
- pytest的测试case收集规则
- [pytest - fixture的使用](#pytest - fixture的使用)
- [skip and xfail](#skip and xfail)
- [pytest - 属性标记测试函数](#pytest - 属性标记测试函数)
- [pytest - 参数化测试](#pytest - 参数化测试)
- [pytest - mock/monkeypatch的使用](#pytest - mock/monkeypatch的使用)
- [pytest - 运行方式](#pytest - 运行方式)
-
- [pytest - 运行方式/命令](#pytest - 运行方式/命令)
- [pytest - 处理测试失败的case](#pytest - 处理测试失败的case)
- [pytest - 测试输出](#pytest - 测试输出)
-
- [捕获 stdout/stderr输出](#捕获 stdout/stderr输出)
- 捕获警告信息
- [pytest - 测试报告](#pytest - 测试报告)
- [pytest - 自带的测试报告](#pytest - 自带的测试报告)
- [pytest + allure测试报告](#pytest + allure测试报告)
- [pytest - 进阶使用](#pytest - 进阶使用)
-
- 安装和使用插件
- 编写插件
- 编写hook函数
- [pytest与现有测试框架 结合](#pytest与现有测试框架 结合)
- pytest调用基于unittest的测试case
- 实现xunit样式的设置
- 设置bash
pytest 基础使用
pytest安装
pip install -U pytest
pytest的测试case收集规则
Conventions for Python test discovery
- 如果未指定有关path的命令行参数,则从当前目录开始查找test case。
- 如果命令指定了查找目录,则会递归的查找这些目录下的文件,除非目录名与
norecursedirs
中的目录名匹配
在这些目录中,搜索以测试包名开头的文件,例如test_*.py
和*_test.py
;test_
是测试包名的前缀,*_test.py
是测试文件的后缀名;
在类之外,带有test_
前缀的测试函数或方法;
在带有前缀(test
/Test
)的测试类中带有前缀test_
的测试函数或方法;带有@staticmethod
和@classmethod
装饰器的方法也会被收集
自定义测试case收集规则
继承unittest.TestCase 来实现
待补充。。。
pytest - fixture的使用
"requesting" fixtures
import pytest
class Fruit:
def __init__(self, name):
self.name = name
self.cubed = False
def cube(self):
self.cubed = True
class FruitSalad:
def __init__(self, *fruit_bowl):
self.fruit = fruit_bowl
self._cube_fruit()
def _cube_fruit(self):
for fruit in self.fruit:
fruit.cube()
@pytest.fixture
def fruit_bowl():
return [Fruit("apple"), Fruit("banana")]
'''
当pytest执行测试函数(test_fruit_salad)时,会检查测试函数签名中的参数(fruit_bowl),并查找与参数同名的fixture对象(fruit_bowl()),pytest一旦找到它们,就会执行fixture对象,并捕获返回结果,然后将结果作为参数传入测试函数
'''
def test_fruit_salad(fruit_bowl):
# Act
fruit_salad = FruitSalad(*fruit_bowl)
# Assert
assert all(fruit.cubed for fruit in fruit_salad.fruit) # def all(__iterable: Iterable[object]) -> bool ,Return True if bool(x) is True for all values x in the iterable.
Fixtures can request other fixtures
import pytest
@pytest.fixture
def first_entry():
return "a"
@pytest.fixture
def order(first_entry):
return [first_entry] # first_entry 的为 a
def test_string(order): # order的值为 ["a"]
order.append("b")
assert order == ["a", "b"]
'''
pytest执行test_sting时,会查找与参数order同名的fixture对象:order(first_entry),然后执行函数order(first_entry),在执行order时,再查找与参数first_entry同名的fixture对象:first_entry(),然后捕获结果:'a',作为参数传递给order函数,再捕获order的函数返回值:['a'],作为参数传递给test_string
'''
fixture是可以重复使用的
一个test/fixture同时可以request多余一个fixture
import pytest
@pytest.fixture
def first_entry():
return "a"
@pytest.fixture
def second_entry():
return 2
@pytest.fixture
def order(first_entry, second_entry):
return [first_entry, second_entry]
@pytest.fixture
def expected_list():
return ["a", 2, 3.0]
def test_string(order, expected_list):
order.append(3.0)
assert order == expected_list
在一次测试中可以多次请求固定数据(返回值会被缓存)
import pytest
@pytest.fixture
def first_entry():
return "a"
@pytest.fixture
def order():
return []
@pytest.fixture
def append_first(order, first_entry):
return order.append(first_entry)
def test_string_only(append_first, order, first_entry):
# print(append_first) # None
# print(order) # ['a']
# print(first_entry) # 'a'
assert order == [first_entry]
自动执行fixture
import pytest
@pytest.fixture
def first_entry():
return "a"
@pytest.fixture
def order(first_entry):
return []
@pytest.fixture(autouse=True)
def append_first(order, first_entry):
return order.append(first_entry)
def test_string_only(order, first_entry):
assert order == [first_entry]
def test_string_and_int(order, first_entry):
order.append(2)
assert order == [first_entry, 2]
scope:可以在类、模块、包、会话之间共享fixtures资源
# aa.py
import smtplib
import pytest
@pytest.fixture(scope="module")
def smtp_connection():
return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
# ======================================================
# test_aa.py
def test_ehlo(smtp_connection):
response, msg = smtp_connection.ehlo()
assert response == 250
assert b"smtp.gmail.com" in msg
assert 0 # for demo purposes
def test_noop(smtp_connection):
response, msg = smtp_connection.noop()
assert response == 250
assert 0 # for demo purposes
fixture 的作用范围
Fixtures are created when first requested by a test, and are destroyed based on their :scope
function
: the default scope, the fixture is destroyed at the end of the test.class
: the fixture is destroyed during teardown of the last test in the class.module
: the fixture is destroyed during teardown of the last test in the module.package
: the fixture is destroyed during teardown of the last test in the package where the fixture is defined, including sub-packages and sub-directories within it.session
: the fixture is destroyed at the end of the test session.
factories as fixtures ,parametrizing fixtures ,Using marks with parametrized fixtures等其他用法以后补充。。。
skip and xfail
待补充。。。
pytest - 属性标记测试函数
待补充。。。
pytest - 参数化测试
待补充。。。
pytest - mock/monkeypatch的使用
待补充。。。
pytest - 运行方式
pytest - 运行方式/命令
忽略某些测试的方式:在命令行里用 --ignore=path 参数
python
usage: pytest [options] [file_or_dir] [file_or_dir] [...]
待补充。。。
pytest - 处理测试失败的case
待补充。。。
pytest - 测试输出
待补充。。。
捕获 stdout/stderr输出
待补充。。。
捕获警告信息
待补充。。。
pytest - 测试报告
待补充。。。
pytest - 自带的测试报告
待补充。。。
pytest + allure测试报告
待补充。。。
pytest - 进阶使用
安装和使用插件
待补充。。。
编写插件
待补充。。。
编写hook函数
待补充。。。
pytest与现有测试框架 结合
待补充。。。
pytest调用基于unittest的测试case
待补充。。。
实现xunit样式的设置
待补充。。。
设置bash
待补充。。。