Skip to content
Development
Skill

/django-tdd

使用 pytest-django 进行 Django 测试的策略、TDD 方法论、factory_boy、Mock 模拟、测试覆盖率以及测试 Django REST Framework API。

From plugin
everything-claude-code
1.8k59 skills15 agents35 commands6 hooks
Install
$ npx -y skills add xu-xiang/everything-claude-code-zh --skill django-tdd --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/django-tdd

Context preview

The summary Claude sees to decide when to auto-load this skill.

使用 pytest-django 进行 Django 测试的策略、TDD 方法论、factory_boy、Mock 模拟、测试覆盖率以及测试 Django REST Framework API。

SKILL.md

django-tdd.SKILL.md
name: django-tdd
description: 使用 pytest-django 进行 Django 测试的策略、TDD 方法论、factory_boy、Mock 模拟、测试覆盖率以及测试 Django REST Framework API。
origin: ECC

使用 TDD 进行 Django 测试

使用 pytest、factory_boy 和 Django REST Framework 对 Django 应用程序进行测试驱动开发(TDD)。

何时激活

  • 编写新的 Django 应用程序时
  • 实现 Django REST Framework API 时
  • 测试 Django 模型(Models)、视图(Views)和序列化器(Serializers)时
  • 为 Django 项目搭建测试基础设施时

Django 的 TDD 工作流

红-绿-重构(Red-Green-Refactor)周期

# 步骤 1: 红(RED) - 编写失败的测试
def test_user_creation():
    user = User.objects.create_user(email='test@example.com', password='testpass123')
    assert user.email == 'test@example.com'
    assert user.check_password('testpass123')
    assert not user.is_staff

# 步骤 2: 绿(GREEN) - 使测试通过
# 创建 User 模型或工厂

# 步骤 3: 重构(REFACTOR) - 在保持测试通过的同时改进代码

配置

pytest 配置

# pytest.ini
[pytest]
DJANGO_SETTINGS_MODULE = config.settings.test
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts =
    --reuse-db
    --nomigrations
    --cov=apps
    --cov-report=html
    --cov-report=term-missing
    --strict-markers
markers =
    slow: 标记为慢速测试
    integration: 标记为集成测试

测试设置(Settings)

# config/settings/test.py
from .base import *

DEBUG = True
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    }
}

# 禁用迁移以提高速度
class DisableMigrations:
    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        return None

MIGRATION_MODULES = DisableMigrations()

# 更快的密码哈希算法
PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.MD5PasswordHasher',
]

# 邮件后端
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

# Celery 设置为同步执行
CELERY_TASK_ALWAYS_EAGER = True
CELERY_TASK_EAGER_PROPAGATES = True

conftest.py

# tests/conftest.py
import pytest
from django.utils import timezone
from django.contrib.auth import get_user_model

User = get_user_model()

@pytest.fixture(autouse=True)
def timezone_settings(settings):
    """确保时区一致。"""
    settings.TIME_ZONE = 'UTC'

@pytest.fixture
def user(db):
    """创建一个测试用户。"""
    return User.objects.create_user(
        email='test@example.com',
        password='testpass123',
        username='testuser'
    )

@pytest.fixture
def admin_user(db):
    """创建一个管理员用户。"""
    return User.objects.create_superuser(
        email='admin@example.com',
        password='adminpass123',
        username='admin'
    )

@pytest.fixture
def authenticated_client(client, user):
    """返回已认证的客户端。"""
    client.force_login(user)
    return client

@pytest.fixture
def api_client():
    """返回 DRF API 客户端。"""
    from rest_framework.test import APIClient
    return APIClient()

@pytest.fixture
def authenticated_api_client(api_client, user):
    """返回已认证的 API 客户端。"""
    api_client.force_authenticate(user=user)
    return api_client

Factory Boy

工厂设置

# tests/factories.py
import factory
from factory import fuzzy
from datetime import datetime, timedelta
from django.contrib.auth import get_user_model
from apps.products.models import Product, Category

User = get_user_model()

class UserFactory(factory.django.DjangoModelFactory):
    """User 模型的工厂类。"""

    class Meta:
        model = User

    email = factory.Sequence(lambda n: f"user{n}@example.com")
    username = factory.Sequence(lambda n: f"user{n}")
    password = factory.PostGenerationMethodCall('set_password', 'testpass123')
    first_name = factory.Faker('first_name')
    last_name = factory.Faker('last_name')
    is_active = True

class CategoryFactory(factory.django.DjangoModelFactory):
    """Category 模型的工厂类。"""

    class Meta:
        model = Category

    name = factory.Faker('word')
    slug = factory.LazyAttribute(lambda obj: obj.name.lower())
    description = factory.Faker('text')

class ProductFactory(factory.django.DjangoModelFactory):
    """Product 模型的工厂类。"""

    class Meta:
        model = Product

    name = factory.Faker('sentence', nb_words=3)
    slug = factory.LazyAttribute(lambda obj: obj.name.lower().replace(' ', '-'))
    description = factory.Faker('text')
    price = fuzzy.FuzzyDecimal(10.00, 1000.00, 2)
    stock = fuzzy.FuzzyInteger(0, 100)
    is_active = True
    category = factory.SubFactory(CategoryFactory)
    created_by = factory.SubFactory(UserFactory)

    @factory.post_generation
    def tags(self, create, extracted, **kwargs):
        """为产品添加标签。"""
        if not create:
            return
        if extracted:
            for tag in extracted:
                self.tags.add(tag)

使用工厂

# tests/test_models.py
import pytest
from tests.factories import ProductFactory, UserFactory

def test_product_creation():
    """测试使用工厂创建产品。"""
    product = ProductFactory(price=100.00, stock=50)
    assert product.price == 100.00
    assert product.stock == 50
    assert product.is_active is True

def test_product_with_tags():
    """测试带有标签的产品。"""
    tags = [TagFactory(name='electronics'), TagFactory(name='new')]
    product = ProductFactory(tags=tags)
    assert product.tags.count() == 2

def test_multiple_products():
    """测试创建多个产品。"""
    products = ProductFactory.create_batch(10)
    assert len(products) == 10

模型(Model)测试

模型测试用例

# tests/test_models.py
import pytest
from django.core.exceptions import ValidationError
from tests.factories import UserFactory, ProductFactory

class TestUserModel:
    """测试 User 模型。"""

    def test_create_user(self, db):
        """测试创建普通用户。"""
        user = UserFactory(email='test@example.com')
        assert user.email == 'test@example.com'
        assert user.check_password('testpass123')
        assert not user.is_staff
        assert not user.is_superuser

    def test_create_superuser(self, db):
        """测试创建超级用户。"""
        user = UserFactory(
            email='admin@example.com',
            is_staff=True,
            is_superuser=True
        )
        assert user.is_staff
        assert
Read more
Ships witheverything-claude-code

🌐 Language / 语言 / 語言 为 AI 智能体(Agent)框架打造的性能优化系统。源自 Anthropic 黑客松获胜作品。 这不仅仅是配置文件。它是一个完整的系统:包含技能(Skills)、本能(Instincts)、内存优化、持续学习、安全扫描以及研究优先的开发模式。这些生产级的智能体(Agents)、钩子(Hooks)、命令(Commands)、规则(Rules)以及 MCP 配置,是在构建真实产品的 10 个多月高强度日常使用中演化而来的。 适用于 Claude Code, Codex,

Get the whole plugin