1. pytest简介
The pytest framework makes it easy to write small, readable tests, and can scale to support complex functional testing for applications and libraries.
pytest是一种卓越的Python测试框架,它提供了简单、高效的方式来编写可以扩展的测试用例。
本文学习pytest的测试用例写法,内容整理自 chatgpt gpt-4-0613 。
相关文档:
2. pytest基本测试
2.1. 准备一个模块
准备一个mathlib模块,包含一个求和函数add():
1 | # mathlib.py |
2.2. 编写测试用例
Python中编写测试用例,一种常见的方式是创建一个以test_
为前缀的函数,这个函数应包含测试用例的名字和内部执行逻辑。
我们想要创建一个测试用例来检验 add 函数,我们可以创建一个 test_mathlib.py 文件:
1 | # test_mathlib.py |
2.3. 执行测试
1 | pytest test_mathlib.py |
2.4. 丰富测试用例
为了使测试更丰富,我们可以使用 @pytest.mark.parametrize
装饰器为函数参数提供多组值:
1 | # test_mathlib.py |
3. pytest进阶测试
3.1. Fixture
Fixture(预置) 是 pytest 提供的一种特殊的函数,它将测试前的准备工作和解除步骤打包成一个函数,以供测试用例调用。这样做可以提高测试的可重用性和代码的可读性。
例如,我们要为数据库相关的测试都创建一个测试数据库,并在测试结束后清理掉,可以写个fixture如下:
1 |
|
然后在测试函数中使用这个 db fixture:
1 | def test_database(db): |
3.2. Mocking
Mocking(模拟) 是一种强大的技术,它可以模拟我们在测试中所依赖的部分的行为。例如,我们的函数可能依赖于一个第三方服务或者数据库,在测试环境中,很可能无法启动这些服务。这时,就可以用 Mock 对象替代这些服务或者数据库。pytest 提供了 unittest.mock 作为内置的 mocking 框架。
下面是一个简单的 mocking 例子,假设我们有一个打印函数 print_content()
,我们并不希望在测试的时候真的打印出来:
1 | from unittest.mock import MagicMock |
3.3. Marker
在 pytest 中,Marker(标记)用于给测试用例添加元数据。比如最常见的 skip 和 xfail,它们会让 pytest 跳过或者期望失败的测试用例。
1 | import pytest |
@pytest.mark.asyncio
也是一个常用的内置装饰器,用于标记需要异步执行的函数。
Python3.5 版本引入了 async / await 关键字支持原生协程,它允许我们编写异步的代码,而不需要依赖于特定的包或者复杂的回调链。然而,pytest 是同步的,它不能原生支持 async / await 式的测试。这就是 pytest.mark.asyncio 装饰器的作用: 它让我们能够以同步的方式来测试异步的代码。
我们也可以自定义 marker。然后我们可以在运行 pytest 的时候指定参数 -m
来只运行有特定标记的测试用例,从而帮助我们更好地管理和运行我们的测试。
1 |
|