Django中使用单元测试
在 Django 中编写单元测试可以帮助你验证模型、视图、表单等组件的正确性。Django 默认使用 unittest
框架,并提供增强的 TestCase
类来简化测试。以下是一个完整的示例和关键步骤:
一、Django 单元测试的核心步骤
-
继承
django.test.TestCase
这是 Django 提供的测试基类,支持数据库事务回滚和测试客户端。 -
编写测试方法
方法名必须以test_
开头,使用断言(如assertEqual
,assertContains
)验证结果。 -
使用测试客户端
通过self.client
模拟 HTTP 请求,测试视图的响应。 -
运行测试
执行python manage.py test
运行所有测试。
测试工具和技巧
-
Client 类:
-
模拟浏览器请求:
self.client.get()
,self.client.post()
-
支持 Cookie、Session 和用户登录(
self.client.login()
)
-
-
断言方法:
-
assertEqual()
: 检查值是否相等 -
assertContains()
: 检查响应内容是否包含文本 -
assertTemplateUsed()
: 检查是否使用了指定模板 -
assertRedirects()
: 检查是否重定向到指定 URL
-
-
测试数据库:
-
每个测试方法在独立事务中运行,数据自动回滚,避免污染。
-
from django.test import TestCase from .models import Depart,Customer from django.urls import reverse # class DepartModelTest(TestCase): # 测试模型 # def test_case_01(self): # dep_obj1 = Depart.objects.create(title="Test Title 99999") # self.assertEqual(dep_obj1.title, 'Test Title 99999') # # dep_obj2 = Depart.objects.create(title="888") # self.assertEqual(dep_obj2.title, '888') class DepartModelTest(TestCase): # 测试模型 def setUp(self): # 善用 setUp() 方法初始化通用数据: # 所有测试方法运行前执行 self.dep_obj = Depart.objects.create(title="Test Title 99999") def test_case_01(self): self.assertEqual(self.dep_obj.title, 'Test Title 99999') self.assertEqual(self.dep_obj.active, 1) class AuthTest(TestCase): # 视图模型 def test_case_01(self): # 访问需要登录的页面(未登录时应重定向) response = self.client.get(reverse("depart_list")) self.assertEqual(response.status_code, 302) # 重定向状态码 # 登录用户后再次访问 # self.client.login(username="admin", password="123456") # 如果使用了auth组件可以这样登录 # response = sels.client.get(reverse("depart_add")) # self.assertEqual(response.status_code, 200) # self.assertTemplateUsed(response, "form.html") # 检查是否使用正确模板 from .views.account import LoginForm class LoginFormTest(TestCase): def test_valid_form(self): # 提交合法数据 form_data = { "role": 1, "username": "root1234", "password": "123456" } form = LoginForm(data=form_data) self.assertTrue(form.is_valid()) # 表单应通过验证 def test_invalid_form(self): # 提交非法数据(价格为负数) form_data = { "role": 3, "username": "root1234", "password": "123456" } form = LoginForm(data=form_data) self.assertFalse(form.is_valid()) # 表单应验证失败 self.assertIn("role", form.errors) # 检查具体错误字段 ######## 若使用 Django REST Framework,可测试 API 端点。 from rest_framework.test import APITestCase from rest_framework import status class LoginAPITest(APITestCase): def test_create_book(self): # 发送 POST 请求 data = { "role": 1, "username": "admin", "password": "123456" } response = self.client.post(reverse("login"), data) # 断言状态码和返回数据 self.assertEqual(response.status_code, status.HTTP_200_OK) """ python manage.py test # 执行所有的测试用例 python manage.py test blog # 执行该app的所有测试用例 python manage.py test blog.tests.DepartViewTest # 执行指定的测试用例 pip install coverage coverage run manage.py test blog coverage report # 查看覆盖率 coverage html # 生成 HTML 报告 """
最佳实践
-
测试覆盖率:使用
coverage
库统计覆盖率:pip install coverage coverage run manage.py test coverage report # 查看覆盖率 coverage html # 生成 HTML 报告