You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django TDD测试报错排查及TDD单元测试模板咨询

问题1:测试失败修复

错误原因

当表单验证成功时,视图返回redirect('questions', pk=pk),重定向响应(状态码302)的response.context为None,直接访问response.context['form']会触发TypeError。

修正后的测试代码

调整测试逻辑,分开验证重定向行为与数据创建,同时新增GET请求场景的表单验证:

def test_can_post_questions(self):
    event = Event.objects.create(name='Python Ghana')
    data = {
        'text': 'how are you?',
    }
    # 发送POST请求
    response = self.client.post(reverse('questions', kwargs={'pk': event.id}), data)
    
    # 验证重定向状态码
    self.assertEqual(response.status_code, 302)
    # 验证数据库新增对应Question记录
    self.assertEqual(Question.objects.filter(event=event, text='how are you?').count(), 1)

# 新增测试:验证GET请求时表单存在于上下文
def test_get_questions_page_has_form(self):
    event = Event.objects.create(name='Python Ghana')
    response = self.client.get(reverse('questions', kwargs={'pk': event.id}))
    
    self.assertEqual(response.status_code, 200)
    self.assertIsInstance(response.context['form'], QuestionCreateForm)

可选:表单验证失败场景测试

如果要覆盖表单验证失败的分支,可新增如下测试:

def test_invalid_question_data_shows_error_form(self):
    event = Event.objects.create(name='Python Ghana')
    # 发送无效数据(假设text为必填项)
    data = {
        'text': '',
    }
    response = self.client.post(reverse('questions', kwargs={'pk': event.id}), data)
    
    self.assertEqual(response.status_code, 200)
    self.assertIsInstance(response.context['form'], QuestionCreateForm)
    # 验证表单携带错误信息
    self.assertTrue(response.context['form'].errors)
问题2:TDD通用模板与Django专用模板

通用单元测试模板(Arrange-Act-Assert模式)

适用于所有Python项目的核心测试结构:

class TestYourFeature:
    def test_scenario_one(self):
        # Arrange:初始化测试数据、环境
        test_data = "测试输入"
        # Act:执行待测试的函数/操作
        result = your_target_function(test_data)
        # Assert:验证结果符合预期
        assert result == "预期输出"

    def test_scenario_two(self):
        # Arrange
        ...
        # Act
        ...
        # Assert
        ...

Django TDD专用模板

模型测试模板

from django.test import TestCase
from .models import YourModel

class TestYourModel(TestCase):
    def test_model_creation(self):
        # Arrange
        instance = YourModel.objects.create(field1="测试值1", field2="测试值2")
        # Assert:验证模型字段与字符串表示
        self.assertEqual(instance.field1, "测试值1")
        self.assertEqual(str(instance), "预期的__str__返回内容")

    def test_custom_model_method(self):
        # Arrange
        instance = YourModel.objects.create(...)
        # Act
        method_result = instance.your_custom_method()
        # Assert
        self.assertEqual(method_result, "预期方法返回值")

视图测试模板

from django.test import TestCase
from django.urls import reverse
from .models import YourModel
from .forms import YourForm

class TestYourView(TestCase):
    def setUp(self):
        # 所有测试共用的初始化数据,避免重复代码
        self.test_instance = YourModel.objects.create(name="测试实例")
        self.view_url = reverse("your_view_name", kwargs={"pk": self.test_instance.pk})

    def test_get_request_renders_template(self):
        # Act
        response = self.client.get(self.view_url)
        # Assert
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, "your_template.html")
        self.assertIsInstance(response.context["form"], YourForm)

    def test_post_valid_data_creates_object(self):
        # Arrange
        valid_data = {"field": "有效输入"}
        # Act
        response = self.client.post(self.view_url, valid_data)
        # Assert
        self.assertEqual(response.status_code, 302)
        self.assertEqual(YourModel.objects.filter(field="有效输入").count(), 1)

    def test_post_invalid_data_shows_errors(self):
        # Arrange
        invalid_data = {"field": ""}  # 缺少必填项
        # Act
        response = self.client.post(self.view_url, invalid_data)
        # Assert
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.context["form"].errors)

表单测试模板

from django.test import TestCase
from .forms import YourForm

class TestYourForm(TestCase):
    def test_valid_form_submission(self):
        # Arrange
        valid_data = {"field1": "有效内容", "field2": "有效内容"}
        # Act
        form = YourForm(data=valid_data)
        # Assert
        self.assertTrue(form.is_valid())

    def test_invalid_form_missing_required_field(self):
        # Arrange
        invalid_data = {"field1": "", "field2": "有效内容"}
        # Act
        form = YourForm(data=invalid_data)
        # Assert
        self.assertFalse(form.is_valid())
        self.assertIn("field1", form.errors)

内容的提问来源于stack exchange,提问作者osahenru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:22:47