描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302472759
以实际项目为范例,内容丰富,示例与图解清晰,全方位介绍Web前端开发测试中的单元测试、自动化测试以及集成测试
全书共分为四部分。*部分为基础篇,总览了前端开发测试中的挑战与测试转型,介绍了测试基础环境的搭建;第二部分为单元测试篇,深入介绍了如何基于Jasmine单元测试框架和gulp、Karma等构建、执行工具对前端JavaScript代码进行单元测试,以及AngularJS单元测试的*实践和代码覆盖率等;第三部分为自动化测试篇,基于Protractor介绍了在Node.js环境下通过Selenium WebDriver全面覆盖各个主流浏览器,进行自动化测试的*实践,包括页面对象模型、性能测试和分布式测试等;第四部分为集成篇,阐述了基于持续集成以实现更快、更可靠的软件交付,展示了如何通过Jenkins与TFS、VSTS和GitHub的集成,实现Web应用的持续测试。
基 础 篇
第1章 前端开发测试总览 …2
1.1 Web技术的发展和挑战 …2
1.2 传统开发流程的局限性 …4
1.3 传统手工测试的局限性 …6
1.4 开发模式的转型 …7
1.4.1 敏捷软件开发 …7
1.4.2 全流程测试 …9
1.4.3 让测试自动化 …11
1.4.4 持续集成 …11
1.4.5 DevOps …12
1.5 本书目标 …13
第2章 搭建测试基础环境 …15
2.1 JavaScript的运行环境Node.js …15
2.1.1 什么是Node.js …15
2.1.2 Node.js的版本发展 …17
2.1.3 安装Node.js …18
2.2 软件包管理系统Node Package Manager(npm) …21
2.2.1 安装和更新npm …21
2.2.2 package.json …22
2.2.3 安装软件包 …23
2.2.4 列出已安装的软件包 …27
2.3 代码编辑器(Visual Studio Code) …28
目 录
2.3.1 安装Visual Studio Code … 28 2.3.2 初识Visual Studio Code … 29 单元测试篇第3章单元测试概论 …34
3.1 单元测试的特性 …34 3.2 单元测试的重要性 …35 3.3 测试金字塔 …37 3.4 测试先行(Test-First) …8 3.4.1 测试驱动开发(Test-Driven Development) …39 3.4.2 行为驱动开发(Behavior-Driven Development) … 40 3.5 Web 前端测试框架 …42 第4章深入Jasmine单元测试 …44
4.1 初识Jasmine …44 4.1.1 获取Jasmine … 44 4.1.2 前端单元测试架构 …46 4.1.3 Jasmine测试框架类库 … 46 4.2 组织测试用例 …48 4.2.1 describe … 48 4.2.2 it … 49 4.2.3 安装和拆卸 … 50 4.2.4 禁用测试套件和挂起测试用例 …54 4.3 创建单元测试 …55 4.3.1 准备测试场景 … 55 4.3.2 编写测试用例 … 56 4.3.3 执行测试 …… 58 4.4 Jasmine的断言 …59 4.4.1 内置匹配器 … 59 4.4.2 自定义匹配器(Custom Matcher) …………………… 67 4.4.3 自定义相等检验器(Custom Equality Tester) ……………… 68
4.4.4 非对称相等检验器(Asymmetric Equality Tester) …………… 70
4.4.5 辅助匹配函数 … 71
4.5 测试替身(Test Double) …74
4.5.1 测试替身的类型 … 74
4.5.2 使用Jasmine Spies …… 77
4.6 测试异步代码 …84
4.6.1 Jasmine的异步支持 … 87
4.6.2 模拟JavaScript Timeout 相关函数……………………… 89
4.7 Jasmine插件 …90
4.7.1 jasmine-ajax … 90
4.7.2 jasmine-jquery … 94
4.8 基于浏览器调试 ……100
第5章单元测试执行工具Karma …………………………102
5.1 初识Karma …102
5.2 安装Karma和相关插件 …104
5.2.1 安装Karma … 104
5.2.2 安装插件 …105
5.3 Karma的配置 …106
5.3.1 生成配置文件 …106
5.3.2 配置文件的说明 ……107
5.4 基于Karma的调试 …115
5.5 前端自动化任务构建工具 …………………………116
5.5.1 gulp和Grunt …116
5.5.2 gulp的API …118
5.5.3 运行gulp任务 …122
5.6 Karma和gulp集成 …123
第6章 AngularJS应用的单元测试 ………………………125
6.1 测试AngularJS应用的挑战 …………………………125
6.2 初识ngMock …127
6.2.1 准备测试环境 …127
6.2.2 理解模块(Module)…128
6.2.3 理解注入机制(Inject) …131
6.3 AngularJS单元测试实践 ………………………138
6.3.1 测试Controller…138
6.3.2 单元测试中的Scope …142
6.3.3 测试HTTP交互…144
6.3.4 测试Directive … 154
6.3.5 测试$timeout和$interval…166
6.3.6 测试Promise … 171
6.3.7 测试$log ……174
6.3.8 测试$exceptionHandler … 175
第7章代码覆盖率 …177
7.1 代码覆盖率的衡量标准 …177
7.1.1 函数覆盖率(Function Coverage) ……………………177
7.1.2 语句覆盖率(Statement Coverage) ……………………178
7.1.3 分支覆盖率(Branch Coverage) ……………………179
7.1.4 条件覆盖率(Condition Coverage) ……………………179
7.2 代码覆盖率的意义 …179
7.3 JavaScript代码覆盖率工具Istanbul ……………………180
7.3.1 安装Istanbul … 181
7.3.2 覆盖率测试 …181
7.3.3 覆盖率阈值 …183
7.3.4 忽略代码 …183
7.3.5 Istanbul工作原理……184
7.4 使用Karma生成覆盖率报告 ………………………185
自动化测试篇第8章走进自动化测试 …188
8.1 自动化测试的优势 …188 8.2 自动化测试实施流程 …189 8.3 自动化测试转型的适应性 …………………………190 8.4 测试工具的选择 ……192 第9章初识Selenium …194
9.1 Selenium发展历史 …194 9.2 Selenium工具套装 …196 9.2.1 Selenium RC … 196 9.2.2 Selenium WebDriver … 197 9.2.3 Selenium Grid … 198 9.2.4 Selenium IDE … 198 第10章Selenium WebDriver 与元素定位 ……………………205
10.1 搭建集成开发环境 …205 10.2 NUnit测试框架 ……207 10.3 编写测试用例 …209 10.4 使用工厂模式创建驱动对象 ………………………212 10.5 定位页面元素 …214 10.5.1 基于id定位 …214 10.5.2 基于Name定位…215 10.5.3 基于ClassName定位 …216 10.5.4 基于TagName 定位 …217 10.5.5 基于LinkText 定位…217 10.5.6 基于PartialLinkText 定位 …218 10.5.7 基于CssSelector定位…219 10.5.8 基于XPath定位 ……220 第11章基于WebDriver 的Protractor 测试框架 ………………227
11.1 WebDriver 的JavaScript绑定 ………………………227
11.1.1 WebDriverJs 与Protractor … 228
11.1.2 Protractor特点概述…229
11.1.3 Protractor的兼容性…230
11.2 搭建Protractor测试环境 …230
11.2.1 安装Protractor编辑器扩展…………………………230
11.2.2 准备AngularJS被测网站 …231
11.2.3 全局安装Protractor与浏览器驱动……………………234
11.2.4 本地安装Protractor与浏览器驱动……………………235
11.2.5 编写测试代码…235
11.2.6 编写配置文件…236
11.2.7 运行测试用例…236
11.2.8 调试……237
11.3 选择JavaScript测试框架 …………………………240
11.3.1 配置JavaScript测试框架…240
11.3.2 JavaScript测试框架的适配器…241
11.4 定位页面元素 …244
11.4.1 基于binding定位……245
11.4.2 基于model定位 ……246
11.4.3 基于options定位 ……246
11.4.4 基于buttonText 定位…247
11.4.5 基于repeater定位 …247
11.4.6 基于js定位…248
11.4.7 链式调用定位操作…249
11.4.8 使用$和$$ … 250
11.4.9 自定义定位策略……251
11.5 异步流程控制 …252
11.5.1 使用Promise …253
11.5.2 定制的ControlFlow … 256
11.5.3 JavaScript测试框架的异步适配器 ……………………259
11.6 页面交互 …260
11.6.1 操作浏览器…260
11.6.2 操作元素…263
11.7 Protractor的等待机制 …265
11.7.1 waitForAngular … 265
11.7.2 使用sleep … 266
11.7.3 隐式等待…266
11.7.4 显式等待…267
11.8 测试非AngularJS程序 …269
第12章使用Selenium Server …273
12.1 Selenium Server环境配置 …………………………273
12.1.1 安装Java JDK … 274
12.1.2 下载Selenium Server Standalone …………………… 275
12.1.3 下载浏览器驱动……276
12.1.4 配置Protractor … 276
12.1.5 启动Selenium Server … 277
12.2 JSON Wire Protocol 与W3C WebDriver 标准 ………………279
12.3 Selenium 3.0 …282
12.4 配置浏览器 …282
12.4.1 Chrome …… 285
12.4.2 Firefox ……285
12.4.3 Edge …… 288
12.4.4 IE ………289
12.4.5 多浏览器测试…291
第13章自动化测试实践 …294
13.1 页面对象模型 …294
13.1.1 关注点分离…295
13.1.2 实现Protractor页面对象…296
13.1.3 页面对象实践…306 13.2 数据驱动测试 …307 13.3 测试报告 …311 13.3.1 控制台报告…312 13.3.2 JUnit报告 …313 13.3.3 HTML报告 …315 13.4 性能测试 …316 13.5 图像匹配 …319 13.6 任务自动化 …322 13.6.1 与gulp集成 …322 13.6.2 npm脚本 …325 第14章分布式自动化测试 …327
14.1 分布式测试概述 …327 14.2 基于Selenium Grid的分布式测试……………………328 14.2.1 启动中央节点…329 14.2.2 注册工作节点…329 14.2.3 执行测试…331 14.3 基于云计算的分布式测试 ………………………333 14.4 配置共享 …336 集成篇第15章持续集成概论…340
15.1 开发流程自动化 …340 15.1.1 什么是持续集成……341 15.1.2 持续集成的价值……341 15.2 持续集成的功能特征 …343 15.2.1 编译……343 15.2.2 测试……344 15.2.3 审计……344 15.2.4 部署……345
15.2.5 反馈……345
15.3 如何实施持续集成 …345
15.3.1 消除误解…345
15.3.2 前提条件…346
15.3.3 CI工具……347
15.3.4 实践准则…348
15.4 选择持续集成工具 …350
第16章持续测试 ……352
16.1 测试策略 …352
16.2 基于Jenkins的持续集成 …353
16.3 集成Team Foundation Server ………………………356
16.3.1 创建项目…356
16.3.2 从Visual Studio Code 提交变更………………………358
16.3.3 配置TFS插件…359
16.3.4 创建并配置Jenkins构建项…………………………360
16.3.5 集成单元测试…364
16.3.6 集成自动化测试……368
16.3.7 邮件反馈…370
16.4 集成Visual Studio Team Services ……………………371
16.5 集成GitHub …376
16.5.1 配置GitHub … 377
16.5.2 配置Jenkins … 379
16.5.3 配置构建任务…380
前 言
笔者多年来一直在微软公司从事与Web开发相关的技术工作,帮助客户维护和处理各种Web应用的突发事件,期间走访了大量客户,为他们提供解决方案或指导意见。我们深深感受到近些年来Web技术的快速发展对Web开发人员、测试人员带来的诸多挑战:
●Web开发是一个开放的、不断演进的、高速迭代的领域。即便是过去一直被诟病为封闭的微软公司也开始拥抱开源世界,提供.NET Core、TypeScript等多项开源和跨平台技术。这对于过去长期在单一厂商平台上进行项目开发的技术人员而言,就更需要积极主动地学习新技术,接受新挑战,以适应变化,满足业务需求。 ●基于JavaScript的前端应用规模越来越大,功能越来越复杂,前端测试已经成为保证产品质量的关键因素。同时,由于Web开发存在测试周期短、更新频繁的特点,传统测试人员需要具备一定的开发能力才能充分利用自动化测试工具来提高测试效率。 ●随着敏捷软件开发方法和DevOps的流行,测试和开发环节之间的界限逐渐变得模糊。传统开发人员需要了解一定的测试方法并具有相应的思维方式,才能设计出良好的测试用例。由于测试和开发环节的融合,无论是开发人员还是测试人员都需要不断提高自身的能力和价值。
本书是笔者在开发测试领域中的实践与经验的总结,希望读者通过对本书的学习,能够掌握Web前端测试的各种技巧,提升自己的能力,迎接新技术的挑战。
本书内容
全书共分四个部分,前两部分为金鑫编写,后两部分为武帅编写。
●部分为基础篇(第1~2章),总览了前端开发测试中的挑战与进行测试转型的方法,以及基于Node.js搭建测试开发基础环境的步骤。 ●第二部分为单元测试篇(第3~7章),基于单元测试理论深入剖析了Jasmine测试框架的结构与各种使用范式,内容覆盖了所有主流单元测试的技巧。然后,结合
gulp、Karma等构建、执行工具对单元测试进行自动化处理。后以实战的形式演示了AngularJS单元测试实践以及Istanbul代码覆盖率的应用等内容。
● 第三部分为自动化测试篇(第8~14章),由浅入深地介绍了Selenium 各个组件的功能特点和WebDriver 在自动化测试中的使用技巧。进而基于Protractor 深入介绍了在Node.js环境下,通过JavaScript代码结合WebDriver 进行自动化测试,并全面覆盖Chrome、Firefox、IE和Edge等主流浏览器的实践,内容包括页面对象模型、性能测试、数据驱动测试和分布式测试等。● 第四部分为集成篇(第15~16 章), 阐述了基于持续集成技术来实现更快、更可靠的软件交付方法,比较了当前主流CI 系统的特点,展示了通过Jenkins 与TFS 、VSTS和GitHub集成来实现Web 应用持续测试的方法。本书适合对象
本书适合所有Web 开发人员、测试人员和项目经理做学习、参考之用。本书涉及的示例代码,读者可从网址https://github.com/FrontEndTesting/webtesting-book-demo 处下载,供对照学习。
致谢
首先,感谢家人对我们利用业余时间编写本书的理解,在漫长的编写过程中始终给予关爱和支持。其次,感谢张量、毛蔚、徐春林和顾洁等微软公司同事的大力鼓励与支持,本书的成书与他们密不可分。
由于笔者学识有限,时间仓促,书中难免出现错误或疏漏,恳请广大读者不吝指正。如果您有什么宝贵意见,请发送邮件至[email protected],我们将不胜感激。
评论
第1章前端开发测试总览第2章搭建测试基础环境
3第1章前端开发测试总览和ASP等生成这样的字符串。换句话说,所谓的“前端”是由后端服务器动态输出而成的HTML网页。在这样的传统Web 应用中,前端只是充当一个展示层,服务调用、网页跳转流程等都需要由后端服务器处理。每当网页功能有所变化时(即使网页内容只有细微变动),浏览器都需要重新发起一个HTTP 请求到服务器,然后由后端服务器重新生成整个页面如图1-1 所示。这种方式不但增加服务器的负担,降低响应速度,而且浏览器重复下载整个网页会浪费网络带宽,对于移动应用很不经济。服务器浏览器初始请求HTML HTML Page Reload Form POST 图1-1 传统网页生命周期而在现代Web 应用中,当网页的部分内容需要更新时,运行在浏览器内的JavaScript 代码通常会向服务器发送Ajax请求,而服务器端只需输出必要的数据,不需要重新构造整个HTML页面,如图1-2所示。Web 前端应用接收到来自服务器的数据后,只需重绘界面上需要变化的部分。这种方式提高了应用的响应速度,改善了用户的使用体验。同时,因为很多用户交互的处理工作可以在浏览器内完成,无需向服务器发送HTTP 请求,服务器和浏览器之间交换的数据量大幅减少,所以服务器负荷降低,响应速度也更快了。Web 应用渐渐开始拥有和桌面应用一样的响应速度和使用体验。服务器浏览器初始请求HTMLJSONAjax{.}图1-2 现代单页应用(SPA )生命周期除了网页内容的更新,Web 应用一部分业务逻辑的处理也从后端服务器慢慢移到前端,Web 前端开发变得越来越重要。而这一切都离不开JavaScript。
JavaScript 是1995年由Netscape 工程师Brendan Eich 花了10天的时间创造出来的,其初目的是为了满足用户浏览网页时产生的交互需求。可以说,JavaScript是为开发Web 应用而诞生的。
自其诞生起的相当长一段时间内,这门在浏览器内执行一些简单的校验和互动的脚本语言常被称之为“玩具语言”,堪称世界上被人误解深的编程语言a。在简洁的外表下,JavaScript其实有着强大的语言特性。它是一种面向对象的动态语言,包含类型、运算符、标准内置对象和方法。其语法来源于 Java和 C,所以这两种语言的许多语法特性同样适用于JavaScript。
随着Web 应用的普及,JavaScript 自身也在不断演化以适应更复杂的编程需求,目前JavaScript已经成为Web 前端的实际标准,也是热门的编程语言之一。各种JavaScript前端框架,包括Ember、AngularJS、React和Vue 等不断涌现。
正因为基于JavaScript 前端应用越来越重要,功能越来越复杂,对前端开发测试带来了极大的挑战。如何保证Web 前端应用的正确性和可靠性成为了各大企业关注的问题。
● 在市场需求的推动下,Web 前端应用规模不断扩大,一个应用可能有成千上万行JavaScript 代码。这些代码用于执行各种复杂的功能,为用户提供不同的交互体验。为了确保它们能实现预期的功能,因此Web 前端应用测试的工作量也需要相应增加。● 相对于传统的桌面应用,用户只要重新刷新浏览器就可以获得版本的网页, 所以Web 前端应用具有天生的快速迭代特征,可以频繁地更新和发布。而激烈的商业竞争也使得Web 前端应用开发周期缩短,对应的测试周期也非常短。● 除了JavaScript代码,Web 前端应用还有各种超链接、表单以及图片等信息,需要保证在不同的操作系统和浏览器上可以正确显示网页的内容。1.2 传统开发流程的局限性在过去二十年或更长的时间中,传统的、非敏捷的瀑布式软件开发模式通常依赖于一
a Douglas Crockford. JavaScript: The World’s Most Misunderstood Programming Language[OL]. [2016]. http://javascript.crockford.com/javascript.html.
第1章前端开发测试总览
个严格的模式化开发流程。通常认为瀑布模型a是Winston W. Royce 在1970年提出的软件开发模型(虽然他并没有使用瀑布waterfall这个单词)。这种方法源自传统工业生产,严格遵循预先计划的需求、分析、设计、编码、测试和部署的步骤顺序进行,每个步骤都有严格分工,由不同的技术人员分别执行。执行步骤的成果作为衡量进度的途径,例如需求规格、设计文档、测试计划和代码审阅等。但随着各种新兴技术的蓬勃发展,特别是在产品快速迭代的需求背景下,这种传统开发流程的局限性日益明显:
1. 自由度低,缺乏灵活性传统模式在项目早期即作出承诺,基于稳定的目标进行阶段性的开发,这种方式自由度低,应对突发情况时缺乏灵活性。众所周知,需求会随着时间而变化,经常出现开发人员努力在设计前完成文档,在编写代码前完成设计,后却因为需求有变化而不得不完全推倒重来的情况,不仅大量工作被浪费,甚至导致对后期需求的变化难以应变,代价高昂。
2. 缺陷发现晚,无法及时反馈传统流程一般在开发阶段接近尾声时才开始测试。虽然在这个阶段进行测试相对容易,但是一些在早期的单元测试中可以轻易发现的缺陷可能要到后阶段才会发现,增加了被遗漏的风险。
由于缺陷发现得很晚,如果要解决问题,则有可能导致错过发布的后期限,再加上手工测试效率低下,任何一次代码变更或缺陷修复对产品的影响都无法迅速反馈给开发人员。随着发现的缺陷越来越多,开发人员只会对变更没有信心,失去持续完善的动力。
3. 协同合作缺失,容易引起团队冲突传统流程中每个步骤都有严格分工,不同阶段的技术人员与上下游的工种往往沟通较少,甚至对产品本身的理解也存在差异。例如,开发人员和测试人员在思维和工作方式上的不同,使得他们对软件需求和测试场景的表述发生歧义,从而引起双方的沟通问题。而这些理解上的差异如果直到测试阶段才被发现的话,则实在太晚,此时双方的冲突与指责对解决问题没有任何帮助。
4. 产品质量无法保证传统流程中常见的一个场景是在项目后期将要交付的阶段,技术人员仓促地从开发环境构建转为脚本配置,而长期在开发环境内依靠手工管理,构建脚本的时候就可能会遇到各种各样的问题,例如接口没有定义、配置文件丢失、组件不工作等。为了解决这些问
a Wikipedia. Waterfall model[OL]. [2016]. https://en.wikipedia.org/wiki/Waterfall_model.
题,技术人员不得不把主要精力放在软件构建上,结果时间成本越来越高,产品质量无法保证,甚至出现产品无法按时交付的情况。
1.3 传统手工测试的局限性软件测试是在规定的条件下对程序进行操作,以发现程序中的错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。软件测试的目的是希望以小的代价尽可能多地找出软件中潜在的错误和缺陷。
首先,测试人员会针对开发人员开发的功能写出测试用例,例如表单应该填入的数据,页面单击顺序,以及后页面期待的显示效果。然后,测试人员会按照用例一步步进行手工检验,如果发现页面行为异常,例如无法打开页面或生成的数据不正确,则会在企业缺陷管理系统中提交缺陷记录,供开发人员进行修正。在开发过程中,如果有新版本编译出来,测试人员需要根据测试用例重新测试,确认是否有新缺陷,或者老缺陷是否已经得到了修正。
长久以来,这种传统的手工测试模式在各大公司广泛应用,并已被证明其能够行之有效地保证产品质量。但伴随着互联网技术的发展,这种传统的测试模式已经显示出越来越多的瓶颈。
1. 重复性工作,测试质量低现在的互联网产品开发讲究的是短平快,小步快走,短则两三天,长则一个星期就会发布新版本。在这短短的时间里,测试人员需要把新版本部署到测试环境,更新数据库,然后对所有测试用例进行手工验证。这个过程时间紧迫,工作量大,而且具有很高的机械性和重复性。当测试人员长期工作在重复性的验证事务上时,往往会因为思维惯性而忽略新出现的问题,后导致不仅测试人员自身缺乏工作热情,而且测试质量更难以保证。
评论
还没有评论。