如何使用Django的TestCase类结合Client进行模拟请求单元测试?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1238个文字,预计阅读时间需要5分钟。
直接继承自`Django.test.TestCase`,而不是使用`unittest.TestCase`——这样做可以避免直接触发Django的数据库事务隔离和测试数据库创建,从而简化测试过程。这样做的好处是测试看起来会成功,但实际上数据并未清空、fixture未加载、ORM操作失效。
常见错误现象:DoesNotExist 报错但手动查数据库明明有数据;assertEqual(qs.count(), 1) 总是为0;测试之间互相污染,第二条测试莫名失败。
- 必须从
django.test.TestCase(或其子类如TransactionTestCase)继承 - 每个测试方法名必须以
test_开头,否则自动被跳过 - 测试运行时,Django会自动创建一个全新的 SQLite(或你配的测试DB),并为每个测试方法包裹在事务里回滚——所以不用手动清理数据
- 如果测试涉及多线程、信号、或需要真实提交事务(比如测试数据库触发器),才考虑换用
TransactionTestCase,但它慢得多
Client模拟请求时URL总404?路由和命名空间别漏配
django.test.Client 不走真实HTTP栈,它直接调用Django视图函数,所以404几乎全是路由配置问题,不是网络或服务问题。
典型场景:本地开发能打开 /api/users/,但测试里 c.get('/api/users/') 返回404。
本文共计1238个文字,预计阅读时间需要5分钟。
直接继承自`Django.test.TestCase`,而不是使用`unittest.TestCase`——这样做可以避免直接触发Django的数据库事务隔离和测试数据库创建,从而简化测试过程。这样做的好处是测试看起来会成功,但实际上数据并未清空、fixture未加载、ORM操作失效。
常见错误现象:DoesNotExist 报错但手动查数据库明明有数据;assertEqual(qs.count(), 1) 总是为0;测试之间互相污染,第二条测试莫名失败。
- 必须从
django.test.TestCase(或其子类如TransactionTestCase)继承 - 每个测试方法名必须以
test_开头,否则自动被跳过 - 测试运行时,Django会自动创建一个全新的 SQLite(或你配的测试DB),并为每个测试方法包裹在事务里回滚——所以不用手动清理数据
- 如果测试涉及多线程、信号、或需要真实提交事务(比如测试数据库触发器),才考虑换用
TransactionTestCase,但它慢得多
Client模拟请求时URL总404?路由和命名空间别漏配
django.test.Client 不走真实HTTP栈,它直接调用Django视图函数,所以404几乎全是路由配置问题,不是网络或服务问题。
典型场景:本地开发能打开 /api/users/,但测试里 c.get('/api/users/') 返回404。

