使用功能测试驱动开发一个最简可用的应用

上一节,我们启用了Django,并且用Selenium驱动浏览器,测试了本地地址http://127.0.0.1,因为只是启动了首页,并没有做任何的页面内容,所以首页显示为空白

这节,我们要在Django框架里开发一个Web应用——“一个代办事项清单的网站”,它是一个很简单的由文本字符串组成的列表,可以使用各种方式扩展功能,如使用持久模型、添加最后期限、提醒和分享功能,还可以改进客户端UI

通过这个代办事项,我们学习如何应用TDD理念


使用功能测试驱动开发一个最简可用的应用

使用Selenium 实现了测试驱动浏览器,让我们能从用户的角度查看应用是如何运作的。因此,我们把这类测试叫作功能测试。这意味着,功能测试在某种程度上可以作为应用的说明书。功能测试的作用是跟踪用户故事(User Story),模拟用户使用某个功能的过程,以及应用应该如何响应用户的操作。

功能测试应该可读、容易理解的故事。为了叙事清楚,可以把测试代码和代码 注释结合起来使用。编写新功能测试时,可以先写注释,勾勒出用户故事的重点。这样写出的测试用例可读,甚至可以作为一种讨论应用需求和功能的方式分享给非程序员看。

TDD 常与敏捷软件开发方法结合在一起使用,我们经常提到的一个概念是“最简可用的应用”,即我们能开发出来的最简单的而且可以使用的应用。下面我们就来开发一个最简可用的应用,尽早试水。

最简可用的待办事项清单其实只要能让用户输入一些待办事项,并且用户下次访问应用时 这些事项还在即可
打开functional_tests.py,开始编写下面的故事

from selenium import webdriver
browser = webdriver.Firefox()# 小明听说有一个很酷的在线待办事项应用
# 她去看了这个应用的首页
browser.get('http://localhost:8000')# 她注意到网页的标题和头部都包含“To-Do”这个词
assert 'To-Do' in browser.title# 应用邀请她输入一个待办事项
# 她在一个文本框中输入了“Buy peacock feathers”(购买孔雀羽毛)
# 伊迪丝的爱好是使用假蝇做饵钓鱼
# 她按回车键后,页面更新了
# 待办事项表格中显示了“1: Buy peacock feathers”
# 页面中又显示了一个文本框,可以输入其他的待办事项
# 她输入了“Use peacock feathers to make a fly”(使用孔雀羽毛做假蝇)
# 伊迪丝做事很有条理
# 页面再次更新,她的清单中显示了这两个待办事项
# 伊迪丝想知道这个网站是否会记住她的清单
# 她看到网站为她生成了一个唯一的URL
# 而且页面中有一些文字解说这个功能
# 她访问那个URL,发现她的待办事项列表还在
# 她很满意,去睡觉了
browser.quit()

除了在测试中加入注释之外,还修改了assert 这行代码,让其查找单词“To-Do”,而不是“Django”。这意味着现在我们期望title返回的是“To-Do”。
启动服务器:

$ python manage.py runserver

然后在另一个shell 中运行测试代码,运行结果报错,

python functional_tests.py

Python标准库中的unittest模块

注意: Unittest框架使用方法大家可以参考官方文档或者去介绍Unittest,有简单的框架方法和实例
(Python语言Unitest框架的使用(一)准备工作:https://blog.csdn.net/sevensolo/article/details/98202271)

通过刚才运行,我们发现断言错误
我们需要修改测试代码,使用assert 关键字的第二个参数

assert ‘To-Do’ in browser.title, "Browser title was " + browser.title

这里使用了unittest 框架,代码后面有具体解释

from selenium import webdriver
import unittestclass NewVisitorTest(unittest.TestCase): # 执行之前执行def setUp(self):self.brower = webdriver.Firefox() # 这里注意Firefox首字母大小写# 执行完之后执行def tearDown(self):self.brower.quit()# 测试用例def test_can_start_a_list_and_retrieve_it_later(self):# 伊迪丝听说有一个很酷的在线待办事项应用# 她去看了这个应用的首页self.brower.get('http://localhost:8000')# 她注意到网页的标题和头部都包含“To-Do”这个词self.assertIn('To-Do', self.brower.title)self.fail('Finish the test!')# 应用邀请她输入一个待办事项if __name__ == '__main__':unittest.main(warnings='ignore')

你可能注意到以下几个地方了。
➊ 测试组织成类的形式,继承自unittest.TestCase。
➋ 测试的主要代码写在名为test_can_start_a_list_and_retrieve_it_later 的方法中。名字以test_ 开头的方法都是测试方法,由测试运行程序运行。类中可以定义多个测试方法。为测试方法起个有意义的名字是个好主意。
➌ setUp 和tearDown 是特殊的方法,分别在各个测试方法之前和之后运行。我使用这两个方法打开和关闭浏览器。注意,这两个方法有点类似try/except 语句,就算测试中出错了,也会运行tearDown 方法。1 测试结束后,Firefox 窗口不会一直停留在桌面上了。
➍ 使用self.assertIn 代替assert 编写测试断言。unittest 提供了很多这种用于编写测试断言的辅助函数,如assertEqual、assertTrue 和assertFalse 等。更多断言辅助函数参见unittest 的文档。
➎ 不管怎样,self.fail 都会失败,生成指定的错误消息。我使用这个方法提醒测试结束了。
➏ 最后是if name == ‘main’ 分句(如果你之前没见过这种用法,我告诉你,Python 脚本使用这个语句检查自己是否在命令行中运行,而不是在其他脚本中导入)。我们调用unittest.main() 启动unittest 的测试运行程序,这个程序会在文件中自动查找测试类和方法,然后运行。
➐ warnings=‘ignore’ 的作用是禁止抛出ResourceWarning 异常。写作本书时这个异常会抛出,但你阅读时我可能已经把这个参数去掉了。你可以把这个参数删掉,看一下效果。

继续运行,报错如下图,断言提示未找到”To-Do“,错误先放下

这样是不是更好了?这个测试清理了Firefox 窗口,显示了一个排版精美的报告,指出运行了几个测试,其中有几个测试失败了,而且assertIn 还显示了一个有利于调试的错误消息。

提交代码

现在是提交代码的好时机,因为已经做了一次完整的修改。我们扩展了功能测试,加入注释说明我们要在最简可用的待办事项清单应用中执行哪些操作。我们还使用Python 中的
unittest 模块及其提供的各种测试辅助函数重写了测试。

执行git status 命令,你会发现只有functional_tests.py 文件的内容变化了

$git status


执行git diff命令,查看上一次提交和当前硬盘中保存内容之间的差异,你会发现functional_tests.py 文 件的变动很大
$ git diff

git commit提代码,-a 的意思是:自动添加已跟踪文件(即已经提交的各文件)中的改动

 $ git commit -a

第一行输入本次提交的备注后:wq!保存退出

Python 测试驱动开发读书笔记(二)使用unittest框架扩展功能测试相关推荐

  1. Python 测试驱动开发读书笔记(准备工作)安装软件

    知识不是靠一篇或者几篇博客就能掌握的,它从来都不是轻松的 当明白这个道理时,我静下心来选择了<Python测试驱动开发>来学习,目前还用不上,但是这本书是今年前半年的计划,新工作也比较忙, ...

  2. Python 测试驱动开发读书笔记(一)使用功能测试协助安装Django

    使用功能测试协助安装Django 本章节知识分为两部分 一是测试驱动开发(Test-Driven Development,TDD)的基础知识: 二是从零开始写一个Web的应用,并用Selenium进行 ...

  3. Python 测试驱动开发读书笔记(三)使用单元测试测试简单的首页

    使用单元测试测试简单的首页 在上一章结尾,我们有一个简单的测试例子,但是这个例子执行是失败的 失败的原因是浏览器的首页标题不是To-Do,从这章开始编写这个应用 第一个Django应用,第一个单元测试 ...

  4. python图像处理《数字图像处理与python实现》读书笔记二:空间滤波

    文章目录 重要! 第三章 空间滤波 概览 3.1 空间滤波基础 3.1.1 空间滤波的机理 3.1.2 空间滤波器模板 3.2 平滑处理 3.2.1 平滑线性空间滤波器 3.2.2 统计排序滤波器 3 ...

  5. python测试驱动开发_使用Python进行测试驱动开发的简单介绍

    python测试驱动开发 by Dmitry Rastorguev 德米特里·拉斯托格夫(Dmitry Rastorguev) 使用Python进行测试驱动开发的简单介绍 (A simple intr ...

  6. 《python 程序设计》读书笔记

    <python 程序设计>读书笔记 笔者对于csdn博客的运用还是不太熟练,希望大家能够见谅.以后会不断提升写作的手法.这篇博客是我在学习python程序设计时候的笔记.我也是选择学习了大 ...

  7. Python测试驱动开发(TDD)

    Python测试驱动开发(TDD) 前言:TDD是一种敏捷开发模式,而不是测试方法. 测试很难 --- 难在坚持,一直做下去. 现在花时间编写的测试不会立即显出功效,要等到很久以后才有作用 --- 或 ...

  8. oracle直查和call哪个更快,让oracle跑的更快1读书笔记二

    当前位置:我的异常网» 数据库 » <>读书笔记二 <>读书笔记二 www.myexceptions.net  网友分享于:2013-08-23  浏览:9次 <> ...

  9. 《How Tomcat Works》读书笔记(二)

    <How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对ser ...

最新文章

  1. Oracle: SQL组合不同字段作为一个查询条件
  2. bloc+rxdart解决代码混乱大问题
  3. 1.VMware安装3个ubuntu14.05
  4. 2021- 10 -9 LeetCode 958. 二叉树的完全性检验(待补完)
  5. KVM学习及应用的七个阶段
  6. 启明云端分享|ESP32摄像头应用方案常遇到的问题
  7. java redis 没密码配置_如何解决redis的NOAUTH Authentication required异常
  8. s2-045 java_S2-045漏洞初步分析
  9. [渝粤教育] 中国地质大学 大学英语(2) 复习题
  10. Python---二分法查找
  11. 从零开始刷Leetcode——数组(448.485.509)
  12. Linux 给用户 赋某个文件夹操作的权限
  13. 时钟分频中的计数值问题
  14. 【转】Python中操作mysql的pymysql模块详解
  15. php7.2 函数安装,讲解PHP7.2源码安装
  16. 推荐几个不错的苹果电脑截图工具
  17. ESP8266烧录选项中的QIO 和 DIO解释
  18. Inc. magazine年度公司Evernote: 小小记事本如何风靡全球
  19. blender导入mmd的pmx模型进行额外建模后,导出pmx模型,出现材质缺失问题的解决方法
  20. 【满分】【华为OD机试真题2023 JAVAJS】查找重复代码

热门文章

  1. python编程(编写opengl程序)
  2. pywin32官方说明文档_为什么你应该看官方文档而不是搜索博客文章
  3. win10浏览器闪退_从没法用到真香!没想到改进了 3 年的 Windows 10 浏览器,竟然这么好用...
  4. bat脚本实现局域网所有存活IP的精准扫描
  5. 2021年青海省大学生首届网络安全知识与技能大赛——赛题回顾及基本讲解
  6. android设置自动开关机,Android开发之设置开机自动启动的几种方法
  7. [Asp.net 开发系列之SignalR篇]专题五:SignalR支持的平台
  8. SPOJ 375 Query on a tree(线段树维护树链剖分)
  9. 算法——动态规划算法
  10. SQLServer基础之数据页类型:GAM,SGAM,PFS