LoongLee's blog

pytest

pytest

定义

pytest 是 Python 最流行的测试框架,以简洁、强大的特性著称,使编写小型或复杂功能测试变得简单。

核心特性

  • 断言内省:详细的断言失败信息
  • 自动发现:自动查找 test_.py 或 _test.py 文件
  • Fixtures:强大的测试数据准备机制
  • 插件系统:丰富的插件生态
  • 参数化测试:使用相同测试逻辑测试多组数据

基本用法

# test_example.py
def test_simple():
    assert True

def test_failure():
    assert 1 + 1 == 3, "Math is broken"

# 类形式
class TestGroup:
    def test_one(self):
        assert True

Fixtures

import pytest
from myapp.models import User

@pytest.fixture
def user():
    return User.objects.create(username="testuser")

@pytest.fixture
def api_client():
    from rest_framework.test import APIClient
    return APIClient()

def test_user_creation(user):
    assert user.username == "testuser"

标记(Markers)

import pytest

@pytest.mark.skip(reason="暂时跳过")
def test_feature():
    pass

@pytest.mark.skipif(sys.version_info < (3, 10), reason="需要 Python 3.10+")
def test_new_syntax():
    pass

@pytest.mark.xfail(reason="已知缺陷")
def test_bug():
    assert False

@pytest.mark.django_db  # 需要数据库访问
def test_model(user):
    assert user.id is not None

参数化测试

import pytest

@pytest.mark.parametrize("input,expected", [
    ("hello", 5),
    ("world", 5),
    ("pytest", 6),
])
def test_string_length(input, expected):
    assert len(input) == expected

模拟(Mocking)

from unittest.mock import patch, MagicMock

@patch('myapp.services.EmailService.send')
def test_email_sent(mock_send):
    mock_send.return_value = True
    result = notify_user()
    mock_send.assert_called_once()
    assert result is True

Django 测试

import pytest
from django.urls import reverse

@pytest.mark.django_db
def test_view(client):
    response = client.get(reverse('home'))
    assert response.status_code == 200

运行测试

# 运行所有测试
pytest

# 运行特定文件
pytest test_example.py

# 运行特定函数
pytest test_example.py::test_simple

# 显示详细输出
pytest -v

# 在失败时停止
pytest -x

# 生成覆盖率报告
pytest --cov=myapp --cov-report=html

相关技术

  • Python - 基础语言
  • Django - Web 框架
  • unittest - Python 标准库测试框架
  • Coverage.py - 代码覆盖率工具

录入自: Django开发实践笔记