Post

【Python库】Pytest编写测试用例

使用Pytest编写测试用例 键测试API 01. Pytest 简介与安装使用 Pytest 是一个功能强大且易于使用的 Python 测试框架 ,用于编写和运行 单元测试 用

先搞技术 阅读 2 点赞 0 评论 0

使用Pytest编写测试用例 键测试API

01. Pytest 简介与安装使用

Pytest 是一个功能强大且易于使用的 Python 测试框架 ,用于编写和运行 单元测试 用例、集成测试和功 能测试,对比 unittest 框架,Pytest 的优势非常明显:

  1. 简单易用 :Pytest 的语法简单明了,学习曲线低,它采用了自然的测试用例编写方式,使得编写测 试代码变得更加简单和直观。

  2. 灵活性 :Pytest 支持多种测试样式,包括函数式、类式、模块级别的测试,甚至支持测试生成器, 而且插件生态非常丰富,可以通过插件来扩展 Pytest 的功能,满足各种测试场景。

  3. 集成性 :Pytest 可以很好地与其他测试工具和框架集成,比如与 JenkinsTravis CICoverage.py 等。它还支持与其他测试框架(如 unittestdoctest )协同工作。

  4. 丰富的输出信息 :Pytest 在测试运行过程中提供丰富的输出信息,包括测试结果、失败原因、详细 的堆栈跟踪等,便于开发人员定位和修复问题。

官网文档:https://docs.pytest.org/en/8.0.x/

安装命令:

uv add pytest httpx

在 Pytest 中,测试用例的编写需要遵循以下规则:

  1. 测试文件以 test_ 开头或 _test 结尾;

  2. 测试类以 Test 开头,并且不能带有 init 方法;

  3. 测试函数以 test_ 开头;

  4. 断言使用基本的 assert 即可;

pytest 会递归查找当前目录及子目录下的所有以 test_ 开始或者 _test 结尾的 Python 脚本,执行其中符 合规则的函数和方法,不需要显示调用,一些常见的运行命令:

# 直接运行文件夹内符合规则的所有用例
pytest folder_name
# 执行某个 Python 文件中的用例
pytest test_file.py
# 执行某个 Python 文件内的某个函数
pytest test_file.py::test_func
​
​
# 执行某个 Python 文件内某个测试类的某个方法
pytest test_file.py::TestClass::test_method
​
​
# 运行测试时显示标准输出(stdout),允许测试中的 print() 语句直接输出到终端
pytest -s
​
​
# 运行测试时显示详细的信息,包括每个测试用例的名称及结果(通过/失败/跳过等),-v 代表 verbose
pytest -v

02. fixture 设置测试环境

在 Pytest 中, fixture 是一种用于为测试函数提供预设数据或设置测试环境的机制

fixture 通常写在 conftest.py 文件中,并且对应的目录及子目录都可以使用 conftest.py 提供的 fixture,如果存在嵌套 conftest.py 文件,则使用的是最接近的 fixture。定义好 fixture 后,在测试函数 中,可以使用同名的参数直接使用,Pytest 会自动注入。

示例:

# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from app.main import app
​
@pytest.fixture(scope="session")
def client() -> TestClient:
    """
    创建一个可供所有测试使用的 TestClient 实例。
    scope="session" 表示这个 fixture 在整个测试会话中只会执行一次,
    这样可以提高效率。
    """
    with TestClient(app) as c:
        yield c
​
# tests/interfaces/endpoints/test_status_routes.py
from fastapi.testclient import TestClient
​
def test_get_status(client: TestClient):
    """创建获取应用状态的端点"""
    # 1.请求获取应用状态api得到响应
    response = client.get("/api/status")
    data = response.json()
    # 2.校验响应内容是否正确
    assert response.status_code == 200
    assert data.get("code") == 200

03. Pytest 参数化测试

在 Pytest 中可以使用 @pytest.mark.parametrize 装饰测试函数,实现使用不同的参数值多次测试运 行相同的代码,以覆盖多种测试场景,可以传递 2 个参数,分别是 参数名参数值

  1. 参数名: query 为单个参数, email, password 为 2 个参数;

  2. 参数值: [None, " 你好,你是 ?"] 为单个参数对应的参数列表, [("admin@imooc.com",

    • "123456"), ("hi@imooc.com", "123456")] 为多个参数对应的 元组参数列表

使用示例如下:

# test/internal/handler/test_app_handler.py
import pytest
from pkg.response import HttpCode
​
class TestAppHandler:
    @pytest.mark.parametrize("query", [None, "你好,你是?"])
    def test_completion(self, query, client):
        r = client.post("/app/completion", json={"query": query})
        assert r.status_code == 200
        if query is None:
            assert r.json().get("code") == HttpCode.VALIDATE_ERROR
        else:
            assert r.json().get("code") == HttpCode.SUCCESS

上面这段代码会重复测试两次,第 1 次传递的 query 值为 None ,并执行代码;第 2 次测试时传递的 query 值为 你好,你是 ? ,通过对参数的不同判断测试结果,以检测代码是否正常运行。

04. pytest.ini 配置运行时

在 Pytest 中,基础的配置可以放在 pytest.ini 配置文件中,格式如下:

[pytest] = config_key config_value

pytest.ini 中的支持的配置项非常多,录入:

[pytest] # 设置测试缓存文件存储在 tmp/.pytest_cache 中 cache_dir = tmp/.pytest_cache

# 设置默认的命令行选项
addopts = -v -s
# 指定 Pytest 在哪些文件中查找测试函数
python_files = test_*.py *_test.py
# 指定 Pytest 在哪些类中查找测试方法
python_classes = Test*
# 指定 Pytest 在哪些函数中查找测试用例
python_functions = test_*

评论