Django中使用单元测试

在 Django 中编写单元测试可以帮助你验证模型、视图、表单等组件的正确性。Django 默认使用 unittest 框架,并提供增强的 TestCase 类来简化测试。以下是一个完整的示例和关键步骤:


一、Django 单元测试的核心步骤

  1. 继承 django.test.TestCase
    这是 Django 提供的测试基类,支持数据库事务回滚和测试客户端。

  2. 编写测试方法
    方法名必须以 test_ 开头,使用断言(如 assertEqual, assertContains)验证结果。

  3. 使用测试客户端
    通过 self.client 模拟 HTTP 请求,测试视图的响应。

  4. 运行测试
    执行 python manage.py test 运行所有测试。

 

测试工具和技巧

  1. Client 类

    • 模拟浏览器请求:self.client.get(), self.client.post()

    • 支持 Cookie、Session 和用户登录(self.client.login()

  2. 断言方法

    • assertEqual(): 检查值是否相等

    • assertContains(): 检查响应内容是否包含文本

    • assertTemplateUsed(): 检查是否使用了指定模板

    • assertRedirects(): 检查是否重定向到指定 URL

  3. 测试数据库

    • 每个测试方法在独立事务中运行,数据自动回滚,避免污染。

 

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 报告

 

posted @ 2021-05-07 20:03  silencio。  阅读(89)  评论(0)    收藏  举报