【有书共读15】Python测试驱动开发 读书笔记06
为视图编写单元测试
这个新测试方法都做了些什么呢?
❶ 创建了一个 HttpRequest 对象,用户在浏览器中请求网页时,Django 看到的就是 HttpRequest 对象。
❷ 把这个 HttpRequest 对象传给 home_page 视图,得到响应。听说响应对象是 HttpResponse 类的实例时,你应该不会觉得奇怪。
❸ 然后,提取响应的 .content。得到的结果是原始字节,即发给用户浏览器的 0 和 1。随后,调用 .decode(),把原始字节转换成发给用户的 HTML 字符串。
❹ 希望响应以 <html> 标签开头,并在结尾处关闭该标签。
❺ 希望响应中有一个 <title> 标签,其内容包含单词“To-Do lists”——因为在功能测试中做了这项测试。
再次说明,单元测试由功能测试驱动,而且更接近于真正的代码。编写单元测试时,按照程序员的方式思考。
运行单元测试,看看进展如何:
现在可以开始适应 TDD 中的单元测试 / 编写代码循环了。
(1) 在终端里运行单元测试,看它们是如何失败的。
(2) 在编辑器中改动最少量的代码,让当前失败的测试通过。
然后不断重复。
-
小幅代码改动:
lists/views.py
def home_page(request): pass
-
运行测试:
html = response.content.decode('utf8') AttributeError: 'NoneType' object has no attribute 'content'
-
编写代码——如你所料,使用 django.http.HttpResponse:
lists/views.py
from django.http import HttpResponse # 在这里编写视图 def home_page(request): return HttpResponse()
-
再运行测试:
self.assertTrue(html.startswith('<html>')) AssertionError: False is not true
-
再编写代码:
lists/views.py
def home_page(request): return HttpResponse('<html>')
-
运行测试:
AssertionError: '<title>To-Do lists</title>' not found in '<html>'
-
编写代码:
lists/views.py
def home_page(request): return HttpResponse('<html><title>To-Do lists</title>')
-
运行测试——快通过了吧?
self.assertTrue(html.endswith('</html>')) AssertionError: False is not true
-
加油,最后一击:
lists/views.py
def home_page(request): return HttpResponse('<html><title>To-Do lists</title></html>')
-
通过了吗?
$ python manage.py test Creating test database for alias 'default'... .. --------------------------------------------------------------------- Ran 2 tests in 0.001s OK System check identified no issues (0 silenced). Destroying test database for alias 'default'...
确实通过了。现在要运行功能测试。如果已经关闭了开发服务器,别忘了启动。感觉这是最后一次运行测试了吧,真是这样吗?
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) --------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 19, in test_can_start_a_list_and_retrieve_it_later self.fail('Finish the test!') AssertionError: Finish the test! --------------------------------------------------------------------- Ran 1 test in 1.609s FAILED (failures=1)
-
启动Django 的开发服务器
python manage.py runserver
-
运行功能测试
python functional_tests.py
-
运行单元测试
python manage.py test
-
“单元测试/ 编写代码”循环
(1) 在终端里运行单元测试。
(2) 在编辑器中改动最少量的代码。
(3) 重复上两步。