之前写的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) #
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

Django学习系列7:使用模板解决“不测试常量”规则,使用模板重构的更多相关文章

  1. Django学习系列之Form基础

     Django学习系列之Form基础 2015-05-15 07:14:57 标签:form django 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追 ...

  2. Django学习系列17:在模板中渲染待办事项

    前面提到的问题中在表格中显示多个待办事项 是最后一个容易解决的问题.要编写一个新单元测试,检查模板是否也能显示多个待办事项: lists/tests.py def test_displays_all_ ...

  3. Django学习系列之模板系统

    一.模板标签 if/else {%  if  %}标签检查一个变量的值是否为真或者等于另外一个值,如果为真,系统会执行{%  if  %}和{%  endif  %}之间的代码块,例如: {% if ...

  4. Django学习系列之模板

    什么是django模板 模板是一个文本,用于分离文档的表现形式和内容,模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签) 模板通常用于产生HTML 如何使用模板 创建一个Tem ...

  5. Django学习之十三:提高页面开发效率减少冗余的模板系统

    目录 Django 模板 模板语法 逻辑语法 函数式过滤器 内置filter 功能tag 注释 内置tag 导入三方tag and filter(load) 过滤器和功能tag的区别 自定义tag和f ...

  6. Django学习系列6:使用selenium测试用户交互

    学习系列5中的单元测试有报错信息,这儿来编写functional_tests.py文件,扩充其中的功能测试 # File: functional_test.py # Author: Rxf # Cre ...

  7. Django学习系列之Form验证

    django表单基础 django表单分类 基于django.forms.Form:所有表单类的父类 基于django.forms.ModelForm:可以和模型类绑定的Form Form验证流程 定 ...

  8. Django学习系列21:为每一个清单添加唯一URL

    现在让我们来解决我们真正的问题,即我们的设计只允许一个全局列表. 我将演示一个关键的TDD技术:如何使用一个渐进的.循序渐进的过程来适应现有的代码,这些过程将您从工作状态转移到工作状态.测试山羊,而不 ...

  9. Django学习系列12:把Python变量传入模板中渲染

    从视图的Python代码中把变量传入HTML模板. 模板中使用哪种句法引入Python对象,要使用的符号{{...}},它会以字符串的形式显示对象: <html> <head> ...

随机推荐

  1. Python 基础语法_Python脚本文件结构

    目录 目录 前言 软件环境 Python Script文件结构 导入模块的流程 Python的包package 最后 前言 Python基础语法这一章,主要记录了Python的文件结构.逻辑运算符.算 ...

  2. MariaDB 连接查询,视图,事物,索引,外键

    1.连接查询 --创建学生表 create table students ( id int unsigned not null auto_increment primary key, name var ...

  3. Java SE 8 docs——Static Methods、Instance Methods、Abstract Methods、Concrete Methods和field

    一.Static Methods.Instance Methods.Abstract Methods.Concrete Methods ——Static Methods:静态方法 ——Instance ...

  4. java 接口default的判断规则

    1.前言 jdk1.8中新增加了default关键字,就是在接口中可以增加默认实现. 因为改动接口所有的实现类都要改动,所以增加了default关键字后不需要修改其他类,默认给所有实现类增加了方法. ...

  5. ubuntu系统熄屏无法唤醒

    ubuntu系统熄屏无法唤醒 解决办法:重启后,安装laptop-mode-tools工具包. 1.检查是否安装了grep laptop-mode-tools 工具包 $ dpkg -l | grep ...

  6. mysql注入常用函数

    system_user()  系统函数名 user()   用户名 current_user()   当前用户名 session_user()    连接数据库的用户名 database()   数据 ...

  7. 【VS开发】【图像处理】GigE和USB3 vision选择?

    [VS开发][图像处理]GigE和USB3 vision选择? 具体得看你现场的应用吧,如 现场需要的工作距离,网线可达到100m以内,USB3.0一般般的5m以内: GigE双端都有卡扣,保证了与相 ...

  8. HTTP协议的概念作用和特点

    Web交互的基本流程 请求:客户端根据服务器地址把数据发送给服务器的过程叫请求. 相应:服务器将请求的处理结果发送给浏览器的过程叫响应. 什么是HTTP? 概念:超文本传输协议. HTTP有什么作用? ...

  9. C++中的三种继承方式

    1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? class Parent { }; class Child : public Parent ...

  10. centos7 源码编译安装 php

    准备工作 下载 PHP 源码包并解压 $ wget https://www.php.net/distributions/php-7.2.19.tar.bz2 $ yum -y install bzip ...