# 测试规范 ## 概述 项目采用 Django 内置测试框架(基于 `unittest`),支持单元测试和集成测试。测试使用 `python manage.py test` 命令运行。 :::tip 测试体系 1. 单元测试(Unit):验证单个函数/方法的逻辑正确性 2. 集成测试(Integration):验证模块间协作、真实数据库操作 ::: ## 目录结构 ``` tests/ ├── test_models.py # 模型测试 ├── test_services.py # Service 层测试 ├── test_views.py # View 层测试 ├── test_forms.py # Form 层测试 └── test_utils.py # 工具函数测试 ``` 或按应用组织: ``` application/example/ ├── models.py ├── services.py ├── views.py ├── forms.py └── tests.py # 该应用的测试 ``` ## Django TestCase 示例 ### 模型测试 ```python from django.test import TestCase from application.example.models import Example class ExampleModelTest(TestCase): """案例模型测试""" def test_create_example(self): """测试创建案例""" example = Example.objects.create( name='测试案例', type=1, status=1, sort=1, create_user='admin' ) self.assertIsNotNone(example.id) self.assertEqual(example.name, '测试案例') self.assertFalse(example.is_delete) def test_soft_delete(self): """测试软删除""" example = Example.objects.create( name='待删除案例', type=1, status=1, sort=1, ) example.is_delete = True example.save() # 验证软删除后查询不到 self.assertFalse( Example.objects.filter(is_delete=False, id=example.id).exists() ) # 验证包含已删除记录可以查到 self.assertTrue( Example.objects.filter(id=example.id).exists() ) ``` ### Service 层测试 ```python from django.test import TestCase, RequestFactory from application.example.services import get_example_page, add_example class ExampleServiceTest(TestCase): """案例 Service 层测试""" def setUp(self): """测试前准备""" self.factory = RequestFactory() # 创建测试数据 Example.objects.create(name='案例1', type=1, status=1, sort=1) Example.objects.create(name='案例2', type=1, status=1, sort=2) def test_get_example_page(self): """测试分页查询""" request = self.factory.get('/example/page', {'pageNo': 1, 'pageSize': 10}) result = get_example_page(request) # 验证返回格式 self.assertEqual(result.status_code, 200) def test_get_example_page_with_filter(self): """测试带筛选条件的分页查询""" request = self.factory.get('/example/page', {'name': '案例1'}) result = get_example_page(request) self.assertEqual(result.status_code, 200) ``` ### View 层测试 ```python from django.test import TestCase, Client from application.example.models import Example class ExampleViewTest(TestCase): """案例 View 层测试""" def setUp(self): """测试前准备""" self.client = Client() # 创建测试数据 Example.objects.create(name='案例1', type=1, status=1, sort=1) def test_page_without_login(self): """测试未登录访问分页接口""" response = self.client.get('/example/page') # 未登录应返回 401 或重定向 self.assertIn(response.status_code, [401, 302]) def test_page_with_login(self): """测试登录后访问分页接口""" # 模拟登录(需根据实际认证方式调整) self.client.force_login(user=User.objects.first()) response = self.client.get('/example/page') self.assertEqual(response.status_code, 200) ``` ### Form 层测试 ```python from django.test import TestCase from application.example.forms import ExampleForm class ExampleFormTest(TestCase): """案例 Form 层测试""" def test_valid_form(self): """测试有效表单""" data = { 'name': '测试案例', 'type': 1, 'status': 1, 'sort': 1, } form = ExampleForm(data) self.assertTrue(form.is_valid()) def test_invalid_form_missing_name(self): """测试缺少必填字段""" data = { 'type': 1, 'status': 1, 'sort': 1, } form = ExampleForm(data) self.assertFalse(form.is_valid()) self.assertIn('name', form.errors) def test_invalid_form_type_out_of_range(self): """测试类型值超出范围""" data = { 'name': '测试案例', 'type': 99, # 超出范围 'status': 1, 'sort': 1, } form = ExampleForm(data) self.assertFalse(form.is_valid()) self.assertIn('type', form.errors) ``` ## 测试命名规范 | 类型 | 文件命名 | 函数命名 | |------|---------|---------| | 模型测试 | `test_*.py` | `test_*` | | Service 测试 | `test_*.py` | `test_*` | | View 测试 | `test_*.py` | `test_*` | | Form 测试 | `test_*.py` | `test_*` | :::tip 函数命名规则 测试函数名应清晰描述被测行为: - `test_create_example`:验证创建案例 - `test_soft_delete`:验证软删除 - `test_get_page_with_filter`:验证带筛选的分页查询 ::: ## 运行命令 ```bash # 运行所有测试 python manage.py test # 运行指定应用的测试 python manage.py test application.example # 运行指定测试文件 python manage.py test application.example.tests # 运行指定测试类 python manage.py test application.example.tests.ExampleModelTest # 运行指定测试方法 python manage.py test application.example.tests.ExampleModelTest.test_create_example # 显示详细输出 python manage.py test -v 2 # 运行测试并显示覆盖率 python manage.py test --parallel ``` ## 测试数据库 Django 测试框架会自动创建测试数据库(命名为 `test_{DATABASE_NAME}`),测试完成后自动销毁。 :::tip 测试数据库配置 - 测试数据库与生产数据库完全隔离 - 每个测试方法运行在独立事务中,测试结束后自动回滚 - 使用 `TestCase` 而非 `TransactionTestCase` 可获得更好的性能 ::: ## 测试覆盖率 ```bash # 安装覆盖率插件 pip install coverage # 运行测试并生成覆盖率报告 coverage run --source='application' manage.py test # 查看报告 coverage report # 生成 HTML 报告 coverage html ``` :::tip 覆盖率目标 - Model 层:90%+ - Service 层:80%+ - View 层:70%+ ::: ## 总结 测试规范使用 Django 内置测试框架,支持模型、Service、View、Form 各层测试。测试文件命名 `test_*.py`,函数命名 `test_*`。使用 `python manage.py test` 运行测试,测试数据库自动创建和销毁。建议使用 `coverage` 工具监控测试覆盖率。