编写你的第一个Django测试:一个简单的视图测试

简介: 本文手把手教你为Django视图编写首个测试:从创建测试数据、验证状态码与内容展示,到覆盖空数据等边界场景。强调测试是开发的安全网,助你重构无忧、信心倍增——简单起步,即刻见效。

如果你和我一样,刚开始接触Django时,写完视图总是一头扎进浏览器,手动刷新页面来测试功能。直到有一天,我维护的项目越来越大,每次添加新功能都担心会不会不小心弄坏旧功能——这时候我才真正理解了测试的重要性。

今天,我想带你一起编写你的第一个Django测试。不用担心,我们会从最简单的视图测试开始,就像我第一次写测试时那样。

为什么要写测试?
想象一下,你正在构建一个简单的博客应用。你写了文章列表视图,一切运行良好。几周后,你添加了文章分类功能,然后突然发现文章列表页打不开了——因为你无意中改动了某个关联关系。

测试就是你的安全网。它让你在修改代码时更有信心,确保现有功能不会被意外破坏。

准备工作
假设我们已经有这样一个简单的视图在blog/views.py中:

from django.shortcuts import render
from .models import Post

def post_list(request):
"""显示所有已发布的博客文章"""
posts = Post.objects.filter(status='published')
return render(request, 'blog/post_list.html', {'posts': posts})
对应的blog/urls.py:

from django.urls import path
from . import views

urlpatterns = [
path('posts/', views.post_list, name='post_list'),
]
创建你的第一个测试
在Django中,测试通常放在每个应用的tests.py文件中。让我们打开blog/tests.py,开始编写测试。

第一步:基础结构
from django.test import TestCase
from django.urls import reverse
from .models import Post

class PostListViewTest(TestCase):
"""测试文章列表视图"""

def setUp(self):
    """测试前的准备工作,每个测试方法运行前都会执行"""
    # 创建一些测试数据
    Post.objects.create(
        title='我的第一篇文章',
        content='这是测试内容',
        status='published'
    )
    Post.objects.create(
        title='草稿文章',
        content='这是草稿',
        status='draft'# 注意这是草稿状态
    )

setUp方法很特别——它会在每个测试方法运行前执行。这样我们可以确保每个测试都在相同的初始状态下开始。

第二步:编写实际的测试
现在我们来写第一个真正的测试方法:

def test_post_list_view_status_code(self):
"""测试视图是否正常返回(状态码200)"""

# 使用reverse通过URL名称获取实际URL
url = reverse('post_list')
response = self.client.get(url)

# 断言:响应状态码应该是200(成功)
self.assertEqual(response.status_code, 200)

这里有几个关键点:

reverse('post_list'):通过名称获取URL,这样即使URL模式改变,测试也不用修改
self.client.get(url):测试客户端模拟浏览器发送GET请求
assertEqual:这是测试的核心,验证实际结果是否符合预期
第三步:测试内容是否正确
仅仅知道页面能打开还不够,我们还需要确保它显示了正确的内容:

def test_post_list_shows_published_posts(self):
"""测试只显示已发布的文章(不显示草稿)"""
url = reverse('post_list')
response = self.client.get(url)

# 应该只显示一篇已发布的文章
self.assertEqual(len(response.context['posts']), 1)

# 检查是否显示了正确的文章
published_post = response.context['posts'][0]
self.assertEqual(published_post.title, '我的第一篇文章')

# 检查HTML中是否包含文章标题
self.assertContains(response, '我的第一篇文章')
# 确保不包含草稿文章的标题
self.assertNotContains(response, '草稿文章')

assertContains是个很方便的方法,它会检查响应内容中是否包含特定文本。

第四步:测试空数据情况
好的测试应该考虑边界情况:

def test_post_list_with_no_published_posts(self):
"""测试没有已发布文章时的情况"""

# 删除所有文章
Post.objects.all().delete()

url = reverse('post_list')
response = self.client.get(url)

# 页面应该仍然能正常打开
self.assertEqual(response.status_code, 200)

# 文章列表应该是空的
self.assertEqual(len(response.context['posts']), 0)

# 可以检查是否显示"暂无文章"之类的提示
self.assertContains(response, '暂时没有文章')

运行测试
现在,让我们运行测试看看效果:

运行特定测试

python manage.py test blog.tests.PostListViewTest

或者运行所有测试

python manage.py test blog
如果一切正常,你会看到类似这样的输出:

...

Ran 3 tests in 0.234s

OK
当测试失败时
如果测试失败了,Django会给你详细的错误信息。比如,如果我们的视图不小心显示了草稿文章,第三个测试就会失败,并告诉我们:

AssertionError: 2 != 1
这意味着发现了2篇文章,但我们预期只有1篇。

更进一步
掌握了基础之后,你可以尝试:

测试需要登录才能访问的视图
测试表单提交
测试API端点
使用工厂函数(Factory Boy)创建测试数据
养成测试习惯
我第一次写测试时,觉得是在浪费时间。但后来发现,这些测试多次在我重构代码时拯救了我。它们不仅帮我发现bug,还让我对代码的设计思考更深入——如果某个功能很难测试,通常意味着代码需要重构。

测试不是负担,而是一种解放。当你有了完整的测试套件,你就可以大胆地重构、添加功能,因为你知道如果有问题,测试会第一时间告诉你。

现在,打开你的项目,为那个你一直担心的视图写个简单的测试吧。从最简单的开始——就像我们刚才做的那样。你会发现,这其实很有趣,而且很有成就感。

记住:好的测试不是追求100%覆盖率,而是测试那些重要的、可能出错的部分。从今天开始,每次写完新功能后,都花几分钟写个测试。这个习惯,你会感谢自己的。

相关文章
|
2月前
|
人工智能 自然语言处理 测试技术
测试工程师的AI扫盲指南:一文搞懂人工智能核心术语
本文面向测试工程师,系统介绍AI核心概念(如ML、DL、LLM、CV、NLP等)、关键技术术语及实战应用(如视觉验证、日志异常识别、RAG、Prompt工程),并提供学习路径与工具实践建议,助力高效开展AI赋能的智能测试。
|
2月前
|
人工智能 Cloud Native 测试技术
2026大厂测试技术栈全景:新人该学什么?
2026年大厂测试技术栈全景:Playwright成自动化首选,k6+云真机+契约测试普及,AI辅助提效。测试工程师需从“质量检查”转向“质量工程”,掌握主流工具,保持技术敏感,以实战能力应对变化。
|
2月前
|
人工智能 算法 测试技术
人工智能测试工程师,需要掌握哪些真正「能落地」的技能?
AI时代,测试工程师正面临能力重构。AI未取代测试,却重塑其核心:从验证功能到保障不确定系统的稳定性与可信性。真正的AI测试需具备三层能力:理解模型逻辑、以数据驱动测试设计、构建智能化自动化体系。转型关键不在知识碎片,而在工程闭环实践。未来属于能让AI系统可靠落地的测试人。
|
8天前
|
缓存 自然语言处理 搜索推荐
大模型上线前,我们到底该怎么测?一份来自一线的检查清单
本文分享大模型对话功能上线前的实战测试经验,直击“无标准答案、状态无限、结果不可复现、判断主观”四大难点,提炼出覆盖功能、性能、安全、体验的六类测试清单及红黄绿三色上线准入标准,助力同行少踩坑、稳上线。
|
2月前
|
传感器 人工智能 架构师
2026实战蓝图:AI Agent全栈开发培训流程与AI Agent职业路线进阶指南
摘要: 2026年,大模型正式进入“行动元年”。AI Agent(智能体)已从的对话接口转变为具备自主逻辑、环境感知与复杂协作能力的数字员工。本文将深度拆解从LLM向Agent覆盖的技术基础逻辑,规划从初级开发者到Agent架构师的职业路径,并提供一套简单的工程化的培训方法论。
979 3
|
22天前
|
人工智能 自然语言处理 测试技术
Prompt Engineering 进阶:如何写出让 AI 自动生成高质量测试用例的提示词?
AI赋能测试用例设计,关键在结构化Prompt:需明确角色、业务、技术栈与约束,并融入等价类、状态图等测试方法论;要求表格化/代码化输出,辅以少样本示例和异常场景深挖。本质是将测试经验精准传递给AI。
|
6天前
|
人工智能 测试技术
AI 写的测试用例,你敢直接用吗?这套判断方法,很多团队正在用
本文直击AI写测试用例的核心矛盾:不问“会不会写”,而聚焦“能不能用”。提出四大落地判断标准——业务贴合度、可执行性、异常覆盖力、规范一致性,帮测试工程师快速甄别AI用例价值,实现从“生成即用”到“工程化采纳”的跃升。
|
8天前
|
数据采集 人工智能 自然语言处理
别再给AI塞提示词了:Skill正在重塑Agent的能力边界
OpenClaw 的 Skill 体系代表 Agent 工程化新范式:不堆提示词,而是将 AI 能力拆解为可描述、可按需加载、可复用的单元。通过渐进式披露与三层加载机制,提升工具调用准确率与系统稳定性,让经验沉淀为可继承、可协作的工程资产。
|
8天前
|
人工智能 测试技术 UED
测试工程师如何用AI拆需求?从“看不懂”到“可测试”
本文分享测试工程师如何巧用AI破解需求理解难题:不直接让AI写用例,而是分六步——先让AI“翻译”需求为可测试语言;再拆解为清晰测试维度;继而查漏补缺边界场景;最后批量生成规范用例。核心是人控方向、AI提效,把“看不懂”转化为“可测试”,守住测试人的判断力与风险意识。
|
26天前
|
人工智能 搜索推荐 IDE
告别断言阻塞!Pytest 原生神器 Subtests 实战教程
Pytest 9.0+ 原生支持 subtests,可在单个测试中运行多个独立子测试:任一失败不中断其余校验,结果聚合展示,动态创建更灵活。告别“断点即终止”,提升多字段/多条件验证效率与可维护性。