Python测试驱动开发:使用Django、Selenium和JavaScript进行Web编程(第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-08-26 00:19:12

点击下载

作者:(英)哈利·帕西瓦尔(Harry J. W. Percival)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Python测试驱动开发:使用Django、Selenium和JavaScript进行Web编程(第2版)

Python测试驱动开发:使用Django、Selenium和JavaScript进行Web编程(第2版)试读:

前言

我试图通过这本书与世人分享我从黑客变成软件工程师的过程。本书主要介绍测试,但很快你就会发现,除此之外还有很多其他内容。

感谢你阅读本书。

如果你购买了本书,我十分感激。如果你看的是免费在线版,我仍然要感谢你,因为你确定这本书值得花时间来阅读。谁知道呢,说不定等你读完之后,会决定为自己或朋友买一本纸质书。

如果你有任何评论、疑问或建议,希望你能写信告诉我。你可以通过电子邮件直接和我联系,地址是 obeythetestinggoat@gmail.com;或者在 Twitter 上联系我,我的用户名是 @hjwp。你还可以访问本书的网站和博客(http://www.obeythetestinggoat.com/),以及邮件列表(https://groups.google.com/forum/#!forum/obey-the-testing-goat-book)。

希望阅读本书能让你身心愉悦,就像我在写作本书时感到享受一样。为什么要写一本关于测试驱动开发的书

我知道你会问:“你是谁,为什么要写这本书,我为什么要读这本书?”

我至今仍然处在编程事业的初期。人们说,不管从事什么工作,都要历经从新手到熟手的过程,最终有可能成为大师。我要说的是,我最多算是个熟练的程序员。但我很幸运,在事业的早期阶段就结识了一群测试驱动开发(Test-Driven Development,TDD)的狂热爱好者,这对我的编程事业产生了极大影响,让我迫不及待地想和所有人分享这段经历。可以说,我很积极地做出了最近这次转变,而且这段学习经历现在还历历在目,我希望能让初学者感同身受。

我在开始学习 Python 时(看的是 Mark Pilgrim 写的 Dive Into Python),偶然知道了 TDD 的概念。我当时就认为:“是的,我绝对知道这个概念的意义所在。”或许你第一次听说 TDD 时也有类似的反应吧。它听起来像是一个非常合理的方案,一个需要养成的非常好的习惯——就像经常刷牙。

随后我做了第一个大型项目。你可能猜到了,有项目就会有客户,有最后期限,有很多事情要做。于是,所有关于 TDD 的好想法都被抛诸脑后。

的确,这对项目没什么影响,对我也没影响。

但只是在初期如此。

一开始,我知道并不真的需要使用 TDD,因为我做的是个小网站,手动检查就能轻易测试出是否能用。在这儿点击链接,在那儿选中下拉菜单选项,就应该有预期的效果,很简单。编写整套测试程序听起来似乎要花费很长时间,而且经过整整三周成熟的代码编写经历,我自负地认为自己已经成为一名出色的程序员了,我能顺利完成这个项目,这没什么难度。

随后,项目变得复杂得可怕,这很快暴露了我的经验不足。

项目不断变大。系统的不同部分之间要开始相互依赖。我尽量遵守良好的开发原则,例如“不要自我重复”(Don't Repeat Yourself,DRY),却被带进了一片危险地带。我很快就用到了多重继承,类的继承有八个层级深,还用到了 eval 语句。

我不敢修改代码,不再像以前一样知道什么依赖什么,也不知道修改某处的代码可能会导致什么后果。噢,天呐,我觉得那部分继承自这里,不,不是继承,是重新定义了,可是却依赖那个类变量。嗯,好吧,如果我再次重定义以前重定义的部分,应该就可以了。我会检查的,可是检查变得更难了。网站中的内容越来越多,手动点击变得不切实际了。最好别动这些能运行的代码,不要重构,就这么凑合吧。

很快,代码就变得像一团麻,丑陋不堪。开发新功能变得很痛苦。

在此之后不久,我幸运地在 Resolver Systems 公司(现在叫 PythonAnywhere)找到了一份工作。这个公司遵循极限编程(Extreme Programming,XP)开发理念。他们向我介绍了严密的 TDD。

虽然之前的经验的确让我认识到自动化测试的好处,但我在每个阶段都心存疑虑。“我的意思是,测试通常来说可能是个不错的主意,但果真如此吗?全部都要测试吗?有些测试看起来完全是在浪费时间……什么?除了单元测试之外还要做功能测试?得了吧,这是多此一举!还要走一遍测试驱动开发中的‘测试 / 小幅度代码改动 / 测试’循环?太荒谬了!我们不需要这种婴儿学步般的过程!既然我们知道正确的答案是什么,为什么不直接跳到最后一步呢?”

相信我!我审视过每一条规则,给每一条捷径提出过建议,为 TDD 的每一个看似毫无意义的做法寻找过理由,最终,我发现了采用 TDD 的明智之处。我记不清在心里说过多少次“谢谢你,测试”,因为功能测试能揭示我们可能永远都无法预测的回归,单元测试能让我避免犯很愚蠢的逻辑错误。从心理学上讲,TDD 大大降低了开发过程中的压力,而且写出的代码让人赏心悦目。

那么,让我告诉你关于 TDD 的一切吧!写作本书的目的

我写这本书的主要目的是要传授一种用于 Web 开发的方法,它可以让 Web 应用变得更好,也能让开发者更愉快。一本书如果只包含一些上网搜索就能找到的知识,那它就没多大的意思了,所以本书不是 Python 句法指南,也不是 Web 开发教程。我希望教会你的,是如何使用 TDD 理念,更加稳妥地实现我们共同的神圣目标——简洁可用的代码。

即便如此,我仍会从零开始使用 Django、Selenium、jQuery 和 Mock 等工具开发一个 Web 应用,不断提到一个真实可用的示例。阅读本书之前,你无须了解这些工具。读完本书后,你会充分了解这些工具,并掌握 TDD 理念。

在极限编程实践中,我们总是结对编程。写这本书时,我设想自己和以前的自己结成对子,向以前的我解释如何使用这些工具,回答为什么要用这种特别的方式编写代码。所以,如果我表现得有点儿屈尊俯就,那是因为我不是那么聪明,我要对自己很有耐心。如果觉得我说话冒犯了你,那是因为我有点儿烦人,经常不认同别人的说法,所以有时要花很多时间论证,说服自己接受他人的观点。本书结构

我将这本书分成了三个部分。● 第一部分(第 1~7 章):基础知识开门见山,介绍如何使用 TDD 开发一个简单的 Web 应用。

我们会先(用 Selenium)写一个功能测试,然后介绍 Django 的

基础知识,包括模型、视图和模板。在每个阶段,我们都会编写

严格的单元测试。除此之外,我还会向你引荐测试山羊。● 第二部分(第 8~17 章):Web 开发要素介绍 Web 开发过程中一些棘手但不可避免的问题,并展示

如何通过测试解决这些问题,包括静态文件、部署到生产环境、

表单数据验证、数据库迁移和令人畏惧的 JavaScript。● 第三部分(第 18~26 章):高级话题介绍模拟技术、集成第三方系统、测试固件、由外而内的

TDD 流程以及持续集成(Continuous Integration,CI)。排版约定

本书使用了下列排版约定。● 黑体表示新术语或强调的内容。● 等宽字体(Constant width)表示程序片段,以及正文中出现的变量、函数名、数据库、

数据类型、环境变量、语句和关键字等。● 加粗等宽字体(Constant width bold)表示应该由用户输入的命令或其他文本。

偶尔使用 [...] 符号表示省略了一些内容,截断较长的输出,或者跳到相关的内容。该图标表示提示或建议。该图标表示提示、建议或一般注记。该图标表示警告或警示。提交勘误

发现了错误或错别字?本书的相关资源放在 GitHub 上,欢迎你随时提交工单和拉取请求:https://github.com/hjwp/Book-TDD-Web-Dev-Python/。

如果发现中文版有错误或错别字,欢迎提交勘误至 http://www.ituring.com.cn/book/2052。使用代码示例

代码示例可到 https://github.com/hjwp/book-example/ 下载,各章的代码都放在单独的分支中,请到 http://www.ituring.com.cn/book/2052“随书下载”处下载。附录 J 中有这个仓库的使用方法。

本书是要帮你完成工作的。一般来说,如果本书提供了示例代码,你可以把它用在你的程序或文档中。除非你使用了很大一部分代码,否则无须联系我们获得许可。比如,用本书的几个代码片段写一个程序就无须获得许可,销售或分发 O'Reilly 图书的示例光盘则需要获得许可;引用本书中的示例代码回答问题无须获得许可,将书中大量的代码放到你的产品文档中则需要获得许可。

我们很希望但并不强制要求你在引用本书内容时加上引用说明。引用说明一般包括书名、作者、出版社和 ISBN。比如:“Test-Driven Development with Python, 2nd edition, by Harry Percival (O'Reilly). Copyright 2017 Harry Percival, 978-1-491-95870-4.”

如果你觉得自己对示例代码的用法超出了上述许可的范围,欢迎你通过 permissions@oreilly.com 与我们联系。O'Reilly Safari

Safari(以前叫 Safari Books Online,http://www.safaribooksonline.com)是会员制平台,为企业、政府、教学人员和个人提供培训和参考资料。

会员可以访问上千种图书、培训视频、学习路径、交互式教程和精心制定的播放列表。这些资源由 250 多家出版社提供,包括 O'Reilly Media、Harvard Business Review、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Adobe、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett 和 Course Technology,等等。

详情请访问 http://oreilly.com/safari。联系我们

请把对本书的评价和问题发给出版社。美国:

O'Reilly Media, Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:

北京市西城区西直门南大街 2 号成铭大厦 C 座 807 室(100035)

奥莱利技术咨询(北京)有限公司

O'Reilly 的每一本书都有专属网页,你可以在那儿找到本书的相关信息,包括勘误表、示例代码以及其他信息。本书的网站地址是:

http://shop.oreilly.com/product/0636920029533.do

对于本书的评论和技术性问题,请发送电子邮件到:bookquestions@oreilly.com。

要了解更多 O'Reilly 图书、培训课程、会议和新闻的信息,请访问以下网站:

http://www.oreilly.com

我们在 Facebook 的地址如下:http://facebook.com/oreilly

请关注我们的 Twitter 动态:http://twitter.com/oreillymedia

我们的 YouTube 视频地址如下:http://www.youtube.com/oreillymedia电子书

如需购买本书电子版,请扫描以下二维码。准备工作和应具备的知识

我假设读者具备了如下的知识,电脑中还应该安装一些软件。了解Python 3,会编程

写这本书时,我考虑到了初学者。但如果你刚接触编程,我假设你已经学习了 Python 基础知识。如果还没学,请阅读一份 Python 初学者教程,或者买一本入门书,比如 Dive Into Python 或《“笨办法”学 Python》,或者出于兴趣,看一下《Python 游戏编程快速上手》。这三本都是很好的入门书。

如果你是经验丰富的程序员,但刚接触 Python,阅读本书应该没问题。Python 简单易懂。

本书中我用的是 Python 3。我在 2013—2014 年写这本书时,Python 3 已经发布好几年了,全世界的开发者正处在一个拐点上,他们更倾向于选择使用 Python 3。可以参照本书内容在 Mac、Windows 和 Linux 中实践。在各种操作系统中安装 Python 的详细说明后文会介绍。本书内容在 Python 3.6 中测试过。如果你使用的是较

低的版本,可能会发现细微的差别(比如 f 字符串句法),

所以如果可以,最好升级 Python。

我不建议使用 Python 2,因为它和 Python 3 之间的区别太大。如果碰巧你的下一个项目使用的是 Python 2,仍然可以运用从本书中学到的知识。不过,当你得到的程序输出和本书不一样时,要花时间判断是因为用了 Python 2,还是因为你确实犯了错——这么做太浪费时间了。

如果你想使用 PythonAnywhere(这是我就职的 PaaS 创业公司),不愿在本地安装 Python,可以先快速阅读一遍附录 A。

无论如何,我希望你能使用 Python,知道如何从命令行启动 Python,也知道如何编辑和运行 Python 文件。再次提醒,如果你有任何疑问,看一下我前面推荐的三本书。如果你已经安装了 Python 2,担心再安装 Python 3 会

破坏之前的版本,那大可以放心,Python 3 和 Python 2 可

以相安无事地共存于同一个系统中,使用虚拟环境的话(本

书就是)更是如此。HTML的工作方式

我还假定你基本了解 Web 的工作方式,知道什么是 HTML、什么是 POST 请求等。如果你对这些概念不熟悉,那么需要找一份 HTML 基础教程看一下,webplateform 网站上列出了一些。如果你知道如何在电脑中创建 HTML 页面,并在浏览器中查看,也知道表单以及它的工作方式,那么或许你就符合我的要求。Django

本书使用 Django 框架,这(或许)是 Python 世界最为人认可的 Web 框架。本书不要求读者事先了解 Django,但如果你刚接触 Python、刚接触 Web 开发,也刚接触测试,偶尔会觉得话题太多,有太多的概念要理解。如果发生了这样的情况,我建议你先把本书放下,找份 Django 教程看看。DjangoGirls 是我所知的对新手最友好的教程。官方教程(https://docs.djangoproject.com/en/1.11/intro/tutorial01/)对有经验的程序员来说是不错的选择。

Django 的安装说明参见后文。JavaScript

本书后半部分有少量 JavaScript。如果你不了解 JavaScript,先别担心。如果你觉得有些看不懂,我到时会推荐一些参考资料给你。关于 IDE如果你来自 Java 或.NET 领域,可能非常想使用

IDE(集成开发环境)编写 Python 代码。IDE 中有各种实用

的工具,例如 VCS 集成。Python 领域也有一些很棒的 IDE。

刚开始我也用过一个 IDE,它对我最初的几个项目很有用。我能建议(只是建议)你别用 IDE 吗?至少在阅读本

书时别用。在 Python 领域,IDE 不是那么重要。写作本书

时,我假定你只使用一个简单的文本编辑器和命令行。某些

时候,它们是你所能使用的全部工具(例如在服务器中),

所以刚开始时值得花时间学习使用基本的工具,理解它们是

如何工作的。即便当你读完本书后决定继续使用 IDE 和其

中的实用工具,这些基本的工具还是唾手可得。需要安装的软件

除了 Python 之外,还要安装以下软件。● Firefox Web 浏览器Selenium 其实能驱动任意一款主流浏览器,不过以 Firefox

举例最简单,因为它跨平台。而且使用 Firefox 还有另外一个好

处——和公司利益没有多少关联。● Git 版本控制系统Git 可在任何一个平台上使用。Windows 安装环境带有

Bash 命令行,这是本书所需的。● 装有 Python 3、Django 1.11 和 Selenium 3 的虚拟环境Python 3.4+ 现在自带 virtualenv 和 pip(早期版本没有,这

是一大进步)。搭建虚拟环境的详细说明参见后文。● Geckodriver这是通过 Selenium 远程控制 Firefox 的驱动。在“安装

Firefox 和 Geckodriver”一节会给出下载链接。针对 Windows 的说明Windows 用户有时会觉得被开源世界忽略了,因为

macOS 和 Linux 太普遍了,很容易让人忘记在 Unix 之外还

有一个世界。使用反斜线作为目录分隔符?盘符?这些是什

么?不过,阅读本书时仍然可以在 Windows 中实践。下面

是一些小提示。1. 在 Windows 中安装 Git 时,一定要选择“Run Git and included Unix tools from the Windows command prompt”(在 Windows 命令提示符中运行 Git 和所含的 Unix 工具)。选择这个选项之后就能使用 Git Bash 了。把 Git Bash 作为主要命令提示符,你就能使用所有实用的 GNU 命令行工具,例如 ls、touch 和 grep,而且目录分隔符也使用斜线表示。2. 在 Git 安装程序中,还要勾选“Use Windows'default console”(使用 Windows 的默认控制台),否则 Python 在 Git Bash 窗口中无法正常使用。3. 安装 Python 3 时,除非已经安装了 Python 2 且想继续将它用作默认版本,否则一定要选中“Add Python 3.6 to PATH”(把 Python 3.6 添加到系统路径中,如图 P-1 所示),这样才能在命令行中顺利运行 Python。测试所有软件是否正确安装的方法是,打开 Git Bash 命令提示符,在任意一个文件夹中执行命令 python 或 pip。图P-1:从安装程序将 Python 加入系统路径针对 MacOS 的说明MacOS 比 Windows 稍微正常一点儿,不过在 Python

3.4 之前,安装 pip 还是一项极具挑战性的任务。Python

3.4 发布后,安装方法变得简单明了。● 使用下载的安装程序就能安装 Python 3.6,省去了很多麻烦。而且,这个安装程序也会自动安装 pip。● Git 安装程序也能顺利运行。测试这些软件是否正常安装的方法和 Windows 类似:

打开一个终端,然后在任意位置执行命令 git、python3 或

pip。如果遇到问题,搜索关键字“system path”和“command not found”,就能找到解决问题的合适资源。或许你还应该检验一下 Homebrew。在 Mac 安装众多 Unix 工具的方式中,它是唯一可信赖1的。 虽然现在 Python 安装程序做得不错,但将来你可能会用到 Homebrew。要使用 Homebrew,需下载大小为 1.1 GB 的 Xcode。不过这有个好处——你得到了一个 C 编译器。1不过我不建议使用 Homebrew 安装 Firefox,因为 Homebrew 会把 Firefox 二进制文件放到一个陌生的位置,Selenium 找不到。虽然这个问题可以解决,但是以常规的方式安装更简单。Git默认使用的编辑器和其他基本配置

后文我会逐步介绍如何使用 Git,不过现在最好做些配置。例如,首次提交时,默认情况下会弹出 vi,这可能让你手足无措。鉴于 vi 有两种模式,因此你有两个选择。其一,学一些基本的 vi 命令(按 i 键进入插入模式,输入文本后再按 键返回常规模式,然后输入 :wq 写入文件并退出)。学会这些命令后,你就加入了一个互助会,这里的人们知道怎么使用这个古老而让人崇敬的文本编辑器。

另外一个选择是直接拒绝这种穿越到 20 世纪 70 年代的荒唐行为,而是配置 Git,让它使用你选择的编辑器。按 键,再输入 :q!,退出 vi,然后修改 Git 使用的默认编辑器。具体方法参见介绍 Git 基本配置的文档。安装Firefox和Geckodriver

从 https://www.mozilla.org/firefox/ 可下载 Windows 和 macOS 的 Firefox 安装包。Linux 可能已经预装了 Firefox;如果没有,使用包管理器安装。

Geckodriver 可从 https://github.com/mozilla/geckodriver/releases 下载。下载后解压,放到系统路径中的某个位置。● 对 macOS 或 Linux 来说,可以放在~/.local/bin 目录中。● 对 Windows 来说,可以放在 Python 的 Scripts 文件夹中。

为了确认是否成功安装,打开一个 Bash 控制台,执行下述命令:geckodriver --versiongeckodriver 0.17.0The source code of this program is available athttps://github.com/mozilla/geckodriver.This program is subject to the terms of the Mozilla Public License 2.0.You can obtain a copy of the license at https://mozilla.org/MPL/2.0/.

如果无法执行这个命令,可能是因为~/.local/bin 不在 PATH 中(针对 Mac 和 Linux 系统)。这个文件夹最好加到 PATH 中,因为使用 pip install --user 安装的 Python 包都存储在这里。把这个文件夹添2加到 .bashrc 文件中的方法如下所示 :2.bashrc 是 Bash 的初始化文件,在家目录中。每次运行 Bash 都会运行这个文件。echo 'PATH=~/.local/bin:$PATH' >> ~/.bashrc

然后关闭终端,重新打开,再次确认能否执行 geckodriver --version 命令。搭建虚拟环境

Python 项目所需的环境使用 virtualenv(virtual environment 的简称)搭建。在不同项目的虚拟环境中可以使用不同的包(例如不同版本的 Django,甚至是不同版本的 Python)。而且虚拟环境中的包不是全局安装的,因此无须 root 权限。

Python 从 3.4 版开始集成了用于搭建虚拟环境的 virtualenv 工具,不过我始终建议使用 virtualenvwrapper 这个辅助工具。先安装 virtualenvwrapper(对 Python 版本没有要求):# 在Windows中pip install virtualenvwrapper# 在macOS/Linux中pip install --user virtualenvwrapper# 然后让Bash自动加载virtualenvwrapperecho "source virtualenvwrapper.sh" >> ~/.bashrcsource ~/.bashrc在 Windows 中,virtualenvwrapper 只能在 Git Bash 中

使用,而不能在常规的命令行中使用。

virtualenvwrapper 把所有虚拟环境都放在一个地方,而且为激活和停用虚拟环境提供了便利的工具。3

下面创建一个名为“superlists” 的虚拟环境,并在里面安装 Python 3:3你可能会问为什么叫“superlists”?我可不想剧透!下一章你就知道了。# 在macOS/Linux中mkvirtualenv --python=python3.6 superlists# 在Windows中mkvirtualenv --python=`py -3.6 -c"import sys; print(sys.executable)"` superlists#(为了得到一个装有Python 3.6的虚拟环境,我们绕了点弯子)激活和停用虚拟环境

阅读本书时,一定要先“激活”你的虚拟环境。你之所以能看出我们处在虚拟环境中,通常是因为提示符中有 (superlists),例如:$(superlists) $

创建虚拟环境之后,就直接激活了虚拟环境。你可以执行 which python 命令再次确认:(superlists) $ which python/home/harry/.virtualenvs/superlists/bin/python#(在Windows中会显示为下面这样# /C/Users/IEUser/.virtualenvs/superlists/Scripts/python)(superlists) $ deactivate$ which python/usr/bin/python$ python --versionPython 2.7.12 # 在我的设备中,虚拟环境外部的“python”默认为Python 2$ workon superlists(superlists) $ which python/home/harry/.virtualenvs/superlists/bin/python(superlists) $ python --versionPython 3.6.0激活虚拟环境的命令是 workon superlists。若想确认

有没有激活,可以看命令提示符中有没有 (superlists) $,或

者执行 which python 命令。安装Django和Selenium

我们将安装 Django 1.11 和最新版 Selenium,即 Selenium 3:(superlists) $ pip install "django<1.12" "selenium<4"Collecting django==1.11.3 Using cached Django-1.11.3-py2.py3-none-any.whlCollecting selenium<4 Using cached selenium-3.4.3-py2.py3-none-any.whlInstalling collected packages: django, seleniumSuccessfully installed django-1.11.3 selenium-3.4.3无法激活虚拟环境时可能会看到的一些错误消息

对刚接触虚拟环境的人来说,肯定会经常忘记激活虚拟环境(说实话,老手也经常犯这个错,比如我)。这时,你会看到一个错误消息,其中的重要部分如下所示:ImportError: No module named selenium

或者是:ImportError: No module named django.core.management

如果遇到这种错误,不要慌,先看看命令提示符中有没有 (superlists)。通常只需执行 workon superlists 就能解决问题。

除此之外,可能还会遇到这个错误:bash: workon: command not found

这表明你前面少做了一步,没有把 virtualenvwrapper 添加到 .bashrc 中。从前文中找到 echo source virtualenvwrapper.sh 命令,再执行一遍。'workon' is not recognized as an internal or external command,operable program or batch file.

这表明你打开的是 Windows 的默认命令提示符 cmd,而不是 Git Bash。关掉 cmd,打开 Git Bash。

编程快乐!上述说明对你没什么用,或者你有更好的说明?请给

我发电子邮件吧,地址是 obeythetestinggoat@gmail.com。配套视频

我为本书录制了一套十集的配套视频(http://oreil.ly/1svTFqB)1,主要针对第一部分的内容。如果你更适合通过视频学习,建议你看看。除了书中的内容之外,这套视频还能让你直观地感受 TDD 流程,了解如何在测试和代码之间切换,与此同时保持思路清晰。1这套视频没有针对第 2 版更新,不过内容基本上依然适用。

我还特意穿了一件亮黄色 T 恤。致谢

要感谢的人很多,没有他们就不会有这本书,就算有也会写得比现在差。

首先感谢某出版社的 Greg,他是第一个鼓励我、让我相信我能写完这本书的人。虽然你们公司在版权问题上思想过于退化,但我还是要感激你个人对我的信任。

感谢 Michael Foord,他以前也是 Resolver Systems 的员工。我写书的最初灵感便来自于他,因为他自己也写了一本书。感谢他一直支持这个项目。感谢我的老板 Giles Thomas,他傻傻地允许他的另一位员工也去写书(不过,我觉得他现在已经修改了标准的雇佣合同,加上了“禁止写书”的条款)。同样也感谢你不断增长的智慧,把我带入了测试领域。

感谢我的另外两位同事,Glenn Jones 和 Hansel Dunlop。你们总是给我提供非常宝贵的意见,而且在过去一年中耐心地陪我录制单轨对话。

感谢我的妻子 Clementine 和家人,没有他们的支持和耐心,我绝对无法写完这本书。很多时间本该和家人在一起难忘地度过,我却把它们都花在了写作上,为此我感到抱歉。开始写作时,我不知道这本书会对我的生活产生什么影响(“在闲暇时间写怎么样?听起来可行……”)。没有你们的支持,我写不完这本书。

感谢技术审校人员 Jonathan Hartley、Nicholas Tollervey 和 Emily Bache。感谢你们的鼓励和珍贵的反馈。尤其是 Emily,她认真阅读了每一章。感谢 Nick 和 Jon,由衷感谢。感谢你们在我身旁,让写作的过程变得不那么孤单。没有你们,这本书的内容会像傻瓜一样废话连篇。

感谢每个放弃自己的时间把意见反馈给我的人,感谢你们的热心肠:Gary Bernhardt、Mark Lavin、Matt O'Donnell、Michael Foord、Hynek Schlawack、Russell Keith-Magee、Andrew Godwin 和 Kenneth Reitz。你们比我聪慧得多,让我避免说一些愚蠢的事情。当然,书中还有很多愚蠢的内容,不过责任肯定不在你们。

感谢我的编辑 Meghan Blanchette,她是一位非常友善可爱的监工。谢谢你为我规划时间,制止我愚蠢的想法,让本书的写作在正确的轨道上行进。感谢 O'Reilly 出版社其他所有为我提供帮助的人,包括 Sarah Schneider、Kara Ebrahim 和 Dan Fauxsmith,感谢你们让我继续使用英式英语。感谢 Charles Roumeliotis 在行文风格和语法上给我的帮助。虽然我们对芝加哥学派引用和标点符号规则的优势有不同观点,但有你在身边我仍然高兴。感谢设计部门为封面绘制了一头山羊。

特别感谢预览版的读者,感谢你们挑出拼写错误,给我反馈和建议,感谢你们提出各种有助于使本书学习曲线变平滑的方法,感谢你们中的大多数人给我鼓励和支持,让我一直写下去。感谢 Jason Wirth、Dave Pawson、Jeff Orr、Kevin De Baere、crainbf、dsisson、Galeran、Michael Allan、James O'Donnell、Marek Turnovec、Sooner Bourne、julz、Cody Farmer、William Vincent、Trey Hunner、David Souther、Tom Perkin、Sorcha Bowler、Jon Poler、Charles Quast、Siddhartha Naithani、Steve Young、Roger Camargo、Wesley Hansen、Johansen Christian Vermeer、Ian Laurain、Sean Robertson、Hari Jayaram、Bayard Randel、Konrad Korzel、Matthew Waller、Julian Harley、Barry McClendon、Simon Jakobi、Angelo Cordon、Jyrki Kajala、Manish Jain、Mahadevan Sreenivasan、Konrad Korzel、Deric Crago、Cosmo Smith、Markus Kemmerling、Andrea Costantini、Daniel Patrick、Ryan Allen、Jason Selby、Greg Vaughan、Jonathan Sundqvist、Richard Bailey、Diane Soini、Dale Stewart、Mark Keaton、Johan Wärlander、Simon Scarfe、Eric Grannan、Marc-Anthony Taylor、Maria McKinley、John McKenna、Rafał Szymański、Roel van der Goot、Ignacio Reguero、TJ Tolton、Jonathan Means、Theodor Nolte、Jungsoo Moon、Craig Cook、Gabriel Ewilazarus、Vincenzo Pandolfo、David“farbish2”、Nico Coetzee、Daniel Gonzalez、Jared Contrascere、赵亮等很多人。如果我遗漏了你的名字,你绝对有权感到委屈。我当然非常感激你,请给我写封信,我会尽我所能把你的名字加上。

最后,我要感谢你,现在的读者,感谢你决定阅读这本书,希望你喜欢。第2版附加致谢

感谢第 2 版的编辑 Nan Barber,感谢 Susan Conant、Kristen Brown 和 O'Reilly 整个团队。再次感谢 Emily 和 Jonathan,感谢你们的技术审阅,还要感谢 Edward Wong 细致的笔记。倘若书中还有错误和不足,责任都在我。

感谢免费版的读者们,感谢你们提出的意见和建议,有些读者甚至发起了拉取请求。感谢 Emre Gonulates、Jésus Gómez、Jordon Birk、James Evans、Iain Houston、Jason DeWitt、Ronnie Raney、Spencer Ogden、Suresh Nimbalkar、Darius、Caco、LeBodro、Jeff、wasabigeek、joegnis、Lars、Mustafa、Jared、Craig、Sorcha、TJ、Ignacio、Roel、Justyna、Nathan、Andrea、Alexandr、bilyanhadzhi、mosegontar、sfarzy、henziger、hunterji、das-g、juanriaza、GeoWill、Windsooon、gonulate,等等。我肯定遗漏了一些名字,为此我深感抱歉。第一部分TDD和Django基础

第一部分我要介绍测试驱动开发(Test-Driven Development,TDD)的基础知识。我们会从零开始开发一个真实的 Web 应用,而且每个阶段都要先写测试。

这一部分涵盖使用 Selenium 完成的功能测试以及单元测试,还会介绍二者之间的区别。我会介绍 TDD 流程,我称之为“单元测试 / 编写代码”循环。我们还要做些重构,说明怎么结合 TDD 使用。因为版本控制对重要的软件工程来说是基本需求,所以我们还会用到版本控制系统(Git)。我会介绍何时以及如何提交,如何把提交集成到 TDD 和 Web 开发的流程中。

我们要使用 Django,它(或许)是 Python 领域之中最受欢迎的 Web 框架。我会试着慢慢介绍 Django 的概念,一次一个,除此之外还会提供很多扩展阅读资料的链接。如果你完全是刚接触 Django,那么我极力推荐你花时间阅读这些资料。如果你感觉有点儿茫然,花几小时读一遍 Django 的官方教程,然后再回来阅读本书。

你还会结识测试山羊……复制粘贴时要小心如果你看的是电子版,那么在阅读的过程之中就会很自

然地会想要复制粘贴书中的代码清单。如果不这么做的话效

果会更好:动手输入能形成肌肉记忆,感觉也更真实。你偶

尔会打错字,这是无法避免的,调试错误也是一项需要学习

的重要技能。除此之外,你还会发现 PDF 格式相当诡异,复制粘贴

时经常会有意想不到的事情发生……第 1 章使用功能测试协助安装Django

TDD 不是天生就会的技术,而是像武术一样的一种技能。就像在功夫电影中一样,你需要一个脾气不好、不可理喻的师傅来强制你学习。我们的师傅是测试山羊。1.1遵从测试山羊的教诲,没有测试什么也别做

在 Python 测试社区中,测试山羊是 TDD 的非官方吉祥物。测试山羊对不同的人有不同的意义。对我来说,它是我脑海中的一个声音,告诉我要一直走在测试这条正确的道路上,就像卡通片中浮现在肩膀上的天使或魔鬼一样,只是没那么咄咄逼人。我希望借由这本书,让测试山羊也扎根于你的脑海中。

虽然还不太确定要做什么,但我们已经决定要开发一个网站。Web 开发的第一步通常是安装和配置 Web 框架。下载这个,安装那个,配置那个,运行这个脚本……但是,使用 TDD 时要转换思维方式。做测试驱动开发时,你的心里要一直记着测试山羊,像山羊一样专注,咩咩地叫着:“先测试,先测试!”

在 TDD 的过程中,第一步始终一样:编写测试。

首先要编写测试,然后运行,看是否和预期一样失败,只有失败了才能继续下一步——编写应用程序。请模仿山羊的声调复述这个过程。我就是这么做的。

山羊的另一个特点是一次只迈一步。因此,不管山壁多么陡峭,它们都不会跌落。看看图 1-1 里的这只山羊!图 1-1:山羊比你想象的要机敏(来源:Flickr 用户 Caitlin Stewart)

我们会碎步向前。使用流行的 Python Web 框架 Django 开发这个应用。

首先,要检查是否安装了 Django,并且能够正常运行。检查的方法是,在本地电脑中能否启动 Django 的开发服务器,并在浏览器中查看能否打开网页。使用浏览器自动化工具 Selenium 完成这个任务。

在你想保存项目代码的地方新建一个 Python 文件,命名为 functional_tests.py,并输入以下代码。如果你喜欢一边输入代码一边像山羊那样轻声念叨,或许会有所帮助:functional_tests.pyfrom selenium import webdriverbrowser = webdriver.Firefox()browser.get('http://localhost:8000')assert 'Django' in browser.title

这是我们编写的第一个功能测试(Functional Test,FT)。后面我会深入说明什么是功能测试,以及它和单元测试的区别。现在,只要能理解这段代码做了什么就行。● 启动一个 Selenium webdriver,打开一个真正的 Firefox 浏览器窗

口。● 在这个浏览器中打开我们期望本地电脑伺服的网页。● 检查(做一个测试断言)这个网页的标题中是否包含单词“Django”。

我们尝试运行一下:$ python functional_tests.py File ".../selenium/webdriver/remote/webdriver.py", line 268, in get self.execute(Command.GET, {'url': url}) File ".../selenium/webdriver/remote/webdriver.py", line 256, in execute self.error_handler.check_response(response) File ".../selenium/webdriver/remote/errorhandler.py", line 194, incheck_response raise exception_class(message, screen, stacktrace)selenium.common.exceptions.WebDriverException: Message: Reached error page: about:neterror?e=connectionFailure&u=http%3A//localhost%3A8000/[...]

你应该会看到弹出了一个浏览器窗口,尝试打开 localhost:8000,然后显示“无法连接”错误页面。这时回到终端,你会看到一个显眼的错误消息,说 Selenium 遇到了一个错误页面。接着,你会看到 Firefox 窗口停留在桌面上,等待你关闭。这可能会让你生气,我们稍后会修正这个问题。如果看到关于导入 Selenium 的错误,或者让你查找“geckodriver”错误,或许你应该往前翻,看一下“准备工

作和应具备的知识”。

现在,得到了一个失败测试。这意味着,我们可以开始开发应用了。别了,罗马数字很多介绍 TDD 的文章都喜欢以罗马数字为例,闹了笑

话,甚至我一开始也是这么写的。如果你好奇,可以查看我

在 GitHub 的页面,地址是 https://github.com/hjwp/。以罗马数字为例有好也有坏。把问题简化,合理地限制

在某一范围内,让你能很好地解说 TDD。但问题是不切实际。因此我才决定要从零开始开发一个

真实的 Web 应用,以此为例介绍 TDD。这是一个简单的

Web 应用,我希望你能把从中学到的知识运用到下一个真

实的项目中。1.2让Django运行起来

你肯定已经读过“准备工作和应具备的知识”了,也安装了 Django。使用 Django 的第一步是创建项目,我们的网站就放在这个项目中。Django 为此提供了一个命令行工具:$ django-admin.py startproject superlists

这个命令会创建一个名为 superlists 的文件夹,并在其中创建一些文件和子文件夹:.├── functional_tests.py├── geckodriver.log└── superlists ├── manage.py └── superlists ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py

在 superlists 文件夹中还有一个名为 superlists 的文件夹。这有点让人困惑,不过确实需要如此。回顾 Django 的历史,你会找到出现这种结构的原因。现在,重要的是知道 superlists/superlists 文件夹的作用是保存应用于整个项目的文件,例如 settings.py 的作用是存储网站的全局配置信息。

你还会注意到 manage.py。这个文件是 Django 的瑞士军刀,作用之一是运行开发服务器。我们来试一下。执行命令 cd superlists,进入顶层文件夹 superlists(我们会经常在这个文件夹中工作),然后执行:$ python manage.py runserverPerforming system checks...System check identified no issues (0 silenced).You have 13 unapplied migration(s). Your project may not work properly untilyou apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.Django version 1.11.3, using settings 'superlists.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.暂时先不管关于“未应用迁移”的消息,第 5 章将讨

论迁移。

这样,Django 的开发服务器便在设备中运行起来了。让这个命令一直运行着,再打开一个命令行窗口(进入刚刚打开的文件夹),在其中再次运行测试:$ python functional_tests.py$因为打开了新的终端窗口,所以要先执行 workon

superlists 命令激活虚拟环境。

我们在命令行中没执行多少操作,但你应该注意两件事:第一,没有丑陋的 AssertionError 了;第二,Selenium 弹出的 Firefox 窗口中显示的页面不一样了。

这虽然看起来没什么大不了,但毕竟是我们第一个通过的测试啊!值得庆祝。

如果感觉有点神奇,不太现实,为什么不手动查看开发服务器,打开浏览器访问 http:// localhost:8000 呢?你会看到如图 1-2 所示的页面。图 1-2:Django 可用了

如果想退出开发服务器,可以回到第一个 shell 中,按 Ctrl-C 键。1.3创建Git仓库

结束这章之前,还要做一件事:把作品提交到版本控制系统(Version Control System,VCS)。如果你是一名经验丰富的程序员,就无须再听我宣讲版本控制了。如果你刚接触 VCS,请相信我,它是必备工具。当项目在几周内无法完成,代码越来越多时,你需要一个工具查看旧版代码、撤销改动、放心地试验新想法,或者只是做个

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载