之前写的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. leetcode 56区间合并

    class Solution { public: static bool cmp(vector<int> a,vector<int> b){ ]<b[]; } vecto ...

  2. pip Fatal error in launcher: Unable to create process using '""'

    如果你装了python2.7, python3.5, 在两个版本的兼容问题上折腾很久了,  通过修改环境变量, 能够出现下面的界面, 恭喜你, 暂时解决了一些问题, 哈哈

  3. 阶段3 2.Spring_09.JdbcTemplate的基本使用_1 今日课程内容介绍

  4. caffe-----silence layer 作用

    最近看到prototxt里面有silence这个层,好奇是干什么用的,而且看源码也出奇的简单: #include <vector> #include "caffe/layers/ ...

  5. java中String中的endsWith()方法

    解释:endsWith() ——此方法测试字符串是否以指定的后缀 suffix 结束. 此方法的定义:public boolean endsWith(String suffix) 我这里判断的是路径是 ...

  6. 【LeetCode】309、最佳买卖股票时机含冷冻期

    Best Time to Buy and Sell Stock with Cooldown 题目等级:Medium 题目描述: Say you have an array for which the ...

  7. AspNet Core Swagger4.0 生成请求model描述

    今天给大家分享 swagger 俩个冷门的小技巧 获取控制器描述 将 IncludeXmlComments 方法第二个参数设置为 true 即可 public static void IncludeX ...

  8. mysql——触发器——概念

    一.触发器 触发器是由事件来出发某个动作.这些事件包括insert语句.update语句和delete语句. 当数据库系统执行这些事件时,就会激活触发器执行相应得动作. 触发器是有insert.upd ...

  9. [BZOJ2144][国家集训队2011]跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上. 每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\),\(c\)这三个位置. 我们要通 ...

  10. MLS(移动最小二乘)

    https://blog.csdn.net/weixin_41484240/article/details/81204113 https://blog.csdn.net/baidu_38127162/ ...