全栈开发人员的特点是能够从头到尾交付并发布一个特性。教程和书籍常常侧重于搭建全栈开发环境和让测试能够进行所需要的“管件(plumbing)”(我综合运用了Angular、Rails、Bootstrap和Postgres)。但对于如何贯穿整个Web开发栈进行应用程序测试,却常常缺少指导。让我们深入研究下这篇文章。我们将学习如何充分利用端到端测试,包括对测试什么以及如何保证那些测试的可靠性和可维护性进行指导。我们还将谈及单元测试以及它们在端到端测试策略中的作用。但首先,我们要理解编写测试的根本目的。\

从根本上讲,测试是为了确保应用程序的行为符合开发者的意愿。它们是自动化的脚本,执行代码并检查其行为是否符合预期。测试编写得越好,就越可以依赖它们为部署把关。如果测试不充分,就需要一个QA团队或者发布有缺陷的软件(两者均意味着用户获得价值的速度比理想情况慢许多)。如果测试充分,就可以自信而快速地发布,不需要批准或者像QA那样缓慢的人工过程。\

对于编写的测试,还必须权衡未来的可维护性。应用程序会变,因此测试也会变。在理想情况下,测试的修改与软件的修改是成正比的。如果你修改了一条错误信息,那么你不会希望大量重写测试套件。但是,如果你彻底地修改了一个用户流程,那么可以预料,将有大量的测试需要重写。\

实际上,这意味着你无法将所有测试都作为端到端的全面集成测试,但是你也不能只进行少得可怜的单元测试。这就关乎如何达成那种平衡。\

测试的类型

\

测试的种类很多,但对于本文而言,我们就谈论两类:端到端测试和单元测试。\

端到端测试模拟用户行为。在Web应用程序中,他们会启动服务器,打开浏览器,到处点击,断言浏览器中发生了特定的事情,让我们相信功能可以正常运行。这些测试会给我们巨大的信心,但是它们缓慢而脆弱,并且同用户界面紧密地耦合在了一起。\

单元测试根据代码单元的公共API运行它们。这些测试需要创建一个类的实例,使用特定的输入调用它的方法,断言被调用的方法达到了预期的效果(通常是返回了预期的输出)。这些测试快速而稳定,并且不会同系统的其他部分紧密地耦合在一起。不过,它们无法让你相信整个系统可以正常运行——只是测试过的代码单元可以正常运行。\

构建一项特性的任务就是要在两类测试之间找到恰当的平衡点。如果端到端测试太多,那么未来修改应用程序就会痛苦而缓慢。如果太少,那么一些不易觉察的缺陷就会进入到生产环境,即使快速测试套件的代码覆盖率为100%。\

从用户体验入手

\

你的软件是向某个用户提供服务,因此,那个用户应该推动你的工作。我不建议使用测试来设计用户体验,因此,要在编写测试之前弄清楚用户将如何使用软件(要么通过试验性代码,要么同一名设计师一起工作)。一旦弄清楚了,就可以开始工作了。\

在理想情况下,你将为用户体验的某个部分创建端到端的测试,并编写代码让其通过测试。在编写那些代码的时候,你会创建单元测试,具体化需要创建或修改(通常是后者)的代码的规范。\

问题是,编写没有用户界面工件(HTML)可供参考的、端到端的失败测试很难。这是因为,大部分端到端测试的形式都是:\

  1. 找到页面上的某个元素; \
  2. 通过某种方式同它交互; \
  3. 证实交互成功; \
  4. 重复上述过程直到测试结束。

这意味着,围绕要发生交互的用户界面元素(DOM对象),你需要有一些规范。当把以JavaScript为基础的交互设计考虑在内时,如果不实际地构建界面,至少是部分地构建,就更难测试了。\

为此,要让一个粗略的UI轮廓在浏览器中运行起来。使用预先准备好的数据,并且不需要考虑备选流程——一次专注于一件事。它运行起来以后,就可以编写测试了。\

在这样做的时候,有两点需要考虑:这个特性需要测试吗?如果需要,该如何测试?\

测试什么

\

虽然在编程上没有愉快路径,但用户经历的代码路径要比代码的可能路径少许多。例如,当用户购买一款产品,根据用户地址、选择的发货方式或者以前的购买历史,我们可能会用不同的方式处理订单。在所有情况下,用户的体验都是一样的,这样,在用户看来,流程只有一个。\

这时,你的目标是测试所有的用户流程。你需要一个测试套件,模拟一个用户做你想要并希望他做的事,并断言你想要提供给该用户的所有体验都工作正常。\

假如你已经知道要测试什么,那应该如何进行呢?\

如何进行端到端测试

\

如果修改了一个流程,那么就要修改那个流程的测试。由于端到端测试模拟用户活动,所以不需要为想要断言的每件事情都编写一个测试。如果用户应该在结算界面上看到三段重要的信息,就不需要编写三个测试——一个测试检查所有三段信息就足够了。因此,当修改一个现有的用户体验时,要找一个现有的、可以改进的测试。\

否则,就需要一个新的测试。记住,你的目标是模拟用户要做的事情。务必要对如何组织测试中的导航和行为开诚布公。用户真地会直接导航到某些深层链接吗?或者他们会点击某个公用的开始页面从而到达他们需要到达的地方吗?\

这很难做,尤其是通常要使用最少的标记实现该功能。测试需要定位特定的DOM元素同其交互,而准确找到你想要同其交互的元素并不总是很简单(或者可能)。你需要“标识(signpost)”。\

标识是专门插入DOM中用于定位感兴趣的元素的。要尽早确定这些标识如何发挥作用。不应该使用原本用于样式化的CSS类来定位DOM元素。这样做意味着前端开发人员改变类名就会破坏测试。也不应该使用被JavaScript代码使用的CSS类或数据属性(比如前缀为js-的类)。这会带来同样的破坏。\

使用前缀为test-的CSS类或者前缀为data-test-的属性是两种常用的技术:

\u0026lt;section class=\"component dark test-checkout-confirmation\"\u0026gt;\  \u0026lt;!-- ... --\u0026gt;\\u0026lt;/section\u0026gt;\\\u0026lt;!-- 或者 --\u0026gt;\\\u0026lt;section class=\"component dark\" data-test-checkout-confirmation\u0026gt;\  \u0026lt;!-- ... --\u0026gt;\\u0026lt;/section\u0026gt;\

\

这可能看上去让人不舒服……也确实是。但是,与将测试耦合到内容或者展示类相比,这就不那么令人讨厌了。这里,你需要寻求一种平衡——不要盲目地使用data-test属性标记每个元素。例如,如果你想点击一个购买特定产品的按钮,那么你真正需要的只是定位某个包含那款产品及购买按钮的元素。

\u0026lt;article data-test-product=\"1234\"\u0026gt;\  \u0026lt;!-- a ton of markup --\u0026gt;\  \u0026lt;input type=\"submit\" name=\"Purchase\" value=\"Purchase\"\u0026gt;\\u0026lt;/article\u0026gt;\\u0026lt;article data-test-product=\"5678\"\u0026gt;\  \u0026lt;!-- a ton of markup --\u0026gt;\  \u0026lt;input type=\"submit\" name=\"Purchase\" value=\"Purchase\"\u0026gt;\\u0026lt;/article\u0026gt;\

\

添加data-test-product属性后,你就能够使用一个像[data-test-product='1234'] input[type='submit']这样的CSS选择器定位产品1234的购买按钮了。\

这意味着你必须修改只为测试而存在的标记,就是说,为了获得你提供给他们的用户体验,用户要下载一些他们不需要的字节。这是一种平衡,但比糟糕的测试覆盖率(对用户的伤害远远超过了HTML中多一些额外的字节)要好。只是得恰到好处。\

当页面上有改变页面内容而又不重新加载的交互(换句话说,使用JavaScript)时,这项技术就更加重要了。\

处理交互

\

当每次点击都重新加载页面时,端到端测试更可靠,因为底层工具知道要等待一个页面重新加载。当用户交互只是改变DOM时,难度就大了,因为工具不知道什么“事情”正在发生,也就无法“等待事情完成”。\

当测试需要同一个不会根据用户动作重新加载的页面交互时,就需要一种方法能够在开始断言发生了什么之前等待DOM操作完成。如果不等待,那么如果测试开始断言时DOM还没有更新,测试就会无谓地失败。\

就像在标记中使用标识定位要操作的DOM元素一样,我们也可以把它们用在这里。任何新增或变化的标记都应该有某种在交互失败或没有发生的情况下不会出现的标识。换句话说,你不必为了等待DOM事件而在测试中进行休眠调用——DOM中应该包含可供测试显式等待的标识。\

例如,假设我们想要测试一个动作为用户生成了一条成功的消息。假设实现方法是发出一个AJAX请求,当调用结束时向DOM中插入一条消息。一个基本的实现可以像下面这样做:

function purchase(productId) {\  $.post(\        \"/products/\

全栈测试:平衡单元测试和端到端测试相关推荐

  1. 自动化测试(二)01-前端测试分为单元测试、集成测试和E2E测试 测试工具对比-适合TDD或 BDD、断言、异步测试 测试工具的类型

    自动化测试(二)01-前端测试分为单元测试.集成测试和E2E测试 & 测试工具对比-适合TDD或 BDD.断言.异步测试 & 测试工具的类型 前端自动化测试 测试是一个庞大的主题,包括 ...

  2. 从编程小白到全栈开发:基于框架开发服务端

    上文中,我们了解了关于服务器端的一些概念知识,尤其是HTTP协议相关的最基本知识点,今天我想跟大家分享一下在平时正真的开发中,是如何来利用和体现这些内容的. 还记得我在<从编程小白到全栈开发:改 ...

  3. Web全栈开发学习笔记—Part2 与服务端通信—d.在服务端将数据Alert出来

    目录 REST Sending Data to the Server Changing the importance of notes Extracting communication with th ...

  4. 全栈工程师实战:从 0 开发云笔记

    专栏亮点 无死角全栈开发:数据库设计.服务端开发.Web 前端开发,三大板块,无死角学习,弥补你的技能短板: 真实项目实战:基于真实项目的实战开发,即学即用,不再迷茫: 规范化开发流程:每个功能,都严 ...

  5. Web前端技术分享:全栈工程师常用的开发工具

    全栈工程师,也叫全端工程师,是指掌握多种技能,并能利用多种技能独立完成产品的人.全栈工程师熟悉多种开发语言,同时具备前端和后台开发能力,从需求分析,原型设计到产品开发,测试,部署,发布全流程都十分熟悉 ...

  6. 【全栈软件测试】软件测试学习路线介绍

    一.前言 1.为何要写软件测试,软件测试很简单. 实际上,软件测试入门简单,但要学透学好,是有很多知识的,入门简单入土难.当你看完学习路线,就知道写的是全栈软件测试,涵盖的内容:全栈软件测试,从零基础 ...

  7. 什么是全栈工程师?需要掌握哪些技能?成为云计算全栈工程师好吗?

    如果一个全栈工程师能够根据原型实现一个完整的MVP(minimum viable product,至少可行的产品),我们通常会认为他十八般武艺样样精通,而且有足够的理由来证明这一点.为了给全栈工程师一 ...

  8. 全数据驱动产品优化,美国互联网公司A/B测试经验分享

     全数据驱动产品优化,美国互联网公司A/B测试经验分享 width="22" height="16" src="http://hits.sinaj ...

  9. python全栈慕课网靠谱么_全栈和python的区别 ?

    1,全栈指的是人. 2,Python是一门编程语言. 全栈: 1,公司创始人/Co Founder全栈:技术+产品+设计+运营+销售+法务+融资+PR.作为公司创始人,在早期真的就是chief eve ...

  10. 从编程小白到全栈开发:服务的调用

    忙带懒,好久没有更新文章了(其实主要是想留给你们一些消化前面文章知识点的时间,哈哈哈). 我们在前文 <从编程小白到全栈开发:基于框架开发服务端>中,初步学习了如何使用Node.js服务端 ...

最新文章

  1. android组件化开发视频教程,教你打造一个Android组件化开发框架
  2. python流程控制-python 流程控制语句
  3. java中8进制常量_下列关于Java语言简单数据类型的说法中,正确的一项是______。A.以0开头的整数代表8进制整型常量B....
  4. 【C++教程】03.第一个程序解析
  5. SQL COUNT() 语法总结及用法【原创】
  6. 普通码农和CTO之间的差距
  7. fishhook源码分析
  8. Unity3D基础24:LineRenderer特效
  9. Python核心编程--学习笔记--8--条件与循环
  10. hdu 1061 Rightmost Digit解题报告
  11. JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础
  12. win7显示时钟与服务器同步失败,win7时间同步出错_Win7电脑时间同步出错怎么办...
  13. 人的一生该怎样度过?
  14. php 实现我的足迹,Wordpress 实现“您的足迹”功能
  15. 二次规划(1):Lagrange法
  16. 《侠盗猎车手-罪恶都市》秘籍
  17. LivePlayer.js播放器遇到悬停英文提示如何切换显示成中文
  18. 可视化DIY制作小程序APP和网站时为什么能千变万化?
  19. (装双系统无法识别硬盘问题)Windows 10 SATA Controller Mode 改为AHCI
  20. ThinkPad 在win10系统上设置Windows Hello

热门文章

  1. python免杀技术---复现+改进----1
  2. 文件操作(二) 其他总结
  3. 25. K 个一组翻转链表
  4. C++ 对引用的理解4
  5. c++详解【new和delete】
  6. arm嵌入式linux应用实例开发pdf,零点起步——ARM嵌入式Linux应用开发入门一书的源代码...
  7. 评估报告有效期过期了怎么办_托福成绩过期了怎么办?
  8. centos给用户添加sudo权限
  9. 【Verilog HDL】语句的并发执行
  10. 数据库简单实用(一)