之前写的lists/tests.py中的单元测试,要查找特定的HTML字符串,但这不是测试HTML的高效方法。
单元测试规则之一“不测试常量”,编写断言检测HTML字符串中是否有制定的字符串序列,不是单元测试应该做的。
单元测试要测试的其实时逻辑,流程控制和配置。
Python代码中插入原始字符串不是处理HTML的正确方式,我们有更好的方式,就是使用模板。把HTML放在一个扩展名为.html的文件中。
让视图函数返回一样的HTML,但使用不同的处理方式,这个过程叫重构,即在功能不变的前提下改进代码。重构的首要原则时不能没有测试,检查一下测试是否通过,测试通过才能保证前后的表现一致。
$ python manage.py test
[...]
OK
把HTML字符串提取出来写入单独的文件,新建用于保存模板的文件夹lists/templates,然后新建文件lists/templates/home.html
<html> <title>To-Do lists</title> </html>
高亮显示,漂亮多了
修改视图函数lists/views.py
from django.shortcuts import render # Create your views here.在这儿编写视图 def home_page(request): return render(request, 'home.html') # render函数中第一个参数是请求对象的,第二个参数是渲染的模板名
现在不构建HttpResponse对象了,转而使用Django中的render函数。Django会自动在所有的应用目录中搜索名为templates的文件夹,然后根据模板中的内容构建一个HttpResponse对象
单元测试
python manage.py test ====================================================================== ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest) # 1 ---------------------------------------------------------------------- Traceback (most recent call last): File "/studydisk/Python_web_TDD/django1x/subperlists/lists/tests.py", line 19, in test_home_page_returns_correct_html response = home_page(request) # 2 File "/studydisk/Python_web_TDD/django1x/subperlists/lists/views.py", line 5, in home_page return render(request, 'home.html') # 3 File "/root/anaconda3/envs/django1.0/lib/python3.5/site-packages/django/shortcuts.py", line 30, in render content = loader.render_to_string(template_name, context, request, using=using) File "/root/anaconda3/envs/django1.0/lib/python3.5/site-packages/django/template/loader.py", line 67, in render_to_string template = get_template(template_name, using=using) File "/root/anaconda3/envs/django1.0/lib/python3.5/site-packages/django/template/loader.py", line 25, in get_template raise TemplateDoesNotExist(template_name, chain=chain) django.template.exceptions.TemplateDoesNotExist: home.html # 4 ---------------------------------------------------------------------- Ran 2 tests in 0.103s FAILED (errors=1) Destroying test database for alias 'default'...
分析错误
1、先看错误是什么测试无法找到模板(#4)
2、确认是哪个测试失败,显然时测试视图HTML的测试(#1)
3、找到导致失败的是测试中哪一行:调用home_page函数那行(# 2)
4、在应用的代码中找到导致失败的部分:调用render函数那段(#3)
为什么Django找不到模板呢?模板的确是在lists/templates文件夹中。
原因是还没有正式在Django中注册lists应用,执行startapp命令以及在项目文件夹中存放一个应用还不够,要告诉Django确实要开发一个应用,并把这个应用添加到文件settings.py中,这样才能保证。
打开setting.py,找到变量INSTALLED_APPS,把lists加进去。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'lists', ]
再次运行测试
$ python manage.py test
[...]
OK