接着上一篇的基础测试用例,这一篇也是属于 django
框架的视图测试, django
视图测试能很好地从视图入手模拟用户的视角习惯来进行逻辑测试。
视图测试
基础测试是我们先编写测试用例,然后测试方法,最后编写代码来修复问题,我们现在来使用工具来测试。
django
提供了一个测试 client
来模拟用户在视图级别与代码交互。
我们可以在 tests.py
中使用它 ,甚至可以在 shell
中使用它。
在 shell
中使用:
python manage.py shell >>> from django.test.utils import setup_test_environment >>> setup_test_environment()
setup_test_environment()
安装模板渲染器,这将允许我们检查响应中的一些其他属性,例如 response.context
,否则将不可用他的属性。
请注意,此方法不会设置测试数据库,因此以下内容将针对现有数据库运行,并且输出可能会略有不同,具体取决于已创建的问题。
如果您的 TIME_ZONE
在 settings.py
设置中不正确,可能会得到其他的结果。
接下来我们需要导入测试客户端类,tests.py
中将使用 django.test.TestCase
,必须带有自己的客户端的类,因此这一步骤是必需的。
>>> from django.test import Client >>> # create an instance of the client for our use >>> client = Client()
根据顺序执行下面shell
(每一步的结果我都会在相应的的命令下面展示出来):
>>> response = client.get("/")
得到下面返回结果:
>>> response.status_code
得到下面返回结果:
>>> from django.urls import reverse >>> response = client.get(reverse("polls:index")) >>> response.status_code
这一步注意:polls
是我加的命名空间,在urls
里面类似这种 app_name = 'polls'
,得到下面返回结果:
>>> response.content
得到下面返回结果:
>>> response.context["latest_question_list"]
得到下面返回结果:
这里 shell
测试就结束了。然后我们用 test.py
来做测试,首先先打开我们的 members/views.py
文件,修改一下 index
视图:
from django.utils import timezone def index(request): # latest_question_list = Question.objects.order_by('-pub_date')[:5] latest_question_list = Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))
在打开 members/views.py
修改方法:
from django.urls import reverse def create_question(question_text, days): """ Create a question with the given `question_text` and published the given number of `days` offset to now (negative for questions published in the past, positive for questions that have yet to be published). """ time = timezone.now() + datetime.timedelta(days=days) return Question.objects.create(question_text=question_text, pub_date=time) class QuestionIndexViewTests(TestCase): def test_past_question(self): """ Questions with a pub_date in the past are displayed on the index page. """ question = create_question(question_text="Past question.", days=-30) response = self.client.get(reverse("members:index")) self.assertQuerySetEqual( response.context["latest_question_list"], [question], )
上面的这个测试方法,我们都是围绕视图 members/index
来进行一些测试。
首先是问题快捷添加功能,create_question
可以减少创建问题过程中的一些重复。
test_past_question
,我们创建一个问题并验证它是否出现在列表中。
执行命令:
python manage.py test members
得到下面返回结果:
如需要做特定测试,可以单独对某个测试用例进行修改,而不需要修改我们本身的代码。
四、总结
既然写测试用例,就要合理对每个方法和视图进行测试,你的代码就不会变得难以管理。这里有一些经验:
- 每个模型或视图单独创建一个
TestClass
, - 针对要测试的条件逻辑采用单独的测试方法,
- 详细描述测试方法名称和他的功能。
在项目开发中,我们更多要从编程工作中去面对编写测试用例,看起来非常麻烦,影响我们的产品开发周期。
实际上它会提高我们后面的效率,其实当你编写测试的任务比花费数小时手动测试应用程序或尝试找出新出现的问题的原因要充实得多。
测试不是发现问题,还能预防问题,测试并不只是我们作为开发简单调试一下。
如果没有测试,应用程序的目的或预期行为可能会相当模糊。
即使是你自己的代码,你有时也会发现自己在里面摸索着试图找出它到底在做什么。
从团队维护的角度,编写自动测试也是大大提高我们团队协作的效率。