【51CTO.com快译】如果您是一名开发者,那么对Node.js一定不陌生。由Node.js提供的各种优秀实践,可以方便您大幅地提高应用的性能。而在JavaScript的支持下,Node.js可以运行在服务器上,以方便开发人员用它来构建企业级应用。目前,像Amazon和LinkedIn之类的知名应用网站都用到了Node.js。当然,Node.js也可以被用在自动化测试的场景中。本文将和您讨论23种有关Node.js的优秀实践。
1.最小化测试用例
为了获得更好的测试结果,我们通常会最小化Node.js中的测试用例,以避免测试数据的相互干扰。也就是说,就算某一项测试失败了,也不会影响到其他测试,并且能够提供更加具体的结果。同时,此法还能最大程度地提高测试的效率。
2.测试用例的命名规则
规范化且有意义的名称对于有效编写测试用例,并实现其预定效果是至关重要的。例如,您应该使用诸如:checkCountryLanguage()和validateUserPhoneNumber()之类的正确命名方式,而不应随机、任意地分配名称。通常,良好的测试用例名称,应当能够明确说明以下内容:
- 待测试的功能。
- 待执行的特定场景。
- 预期的测试结果。
3.使用BDD样式
使用与被测产品类似或相同的语言,来编写测试样式的好处在于,既能让用户一目了然地理解测试流程和期望,又能将实际的代码部分对非技术相关人员进行隐藏。行为驱动开发(Behavior Driven Development,BDD)是这种方法的优秀示例,它不但易于操作,而且能与Node.js进行良好的集成,因此备受企业用户的欢迎。
4.实施断言(Assertions)
作为测试用例的重要组成部分,断言的声明性语句能够通过提供布尔输出,协助测试人员验证是否已按照预期执行了测试用例。在Node.js的自动化测试中,断言通过self-explanatory的方式,不但可以减少代码总量,并且能够提供可靠的结果。对于开发人员而言,断言既可以节省他们检查完整输出的时间,又能够通过将每个步骤中的响应结果,与期望值做比较,以判断是否通过了测试。整个过程都可以通过节点中的Chai库,来轻松实现的。例如,我们可以构建如下断言:expect(todayWeather).to.be.(clear);
5.最小化测试用例的帮助和抽象
作为一个完整的单元,良好的测试用例代码往往具有良好的结构,以及最少的外部交互(或称耦合)。新手开发人员或测试人员不必通过借鉴另一个测试,来理解先前的测试,也不必遍历完整的测试用例结构。因此,最小化测试用例的帮助和抽象,可以让用例更加简单易懂,且易于维护。
6.测试运行程序
测试运行程序不但带有各种库与工具,还包含许多单元测试的源代码目录。它能够以用户可读的日志文件形式,在其控制台上呈现测试结果。目前,市场上的众多测试运行程序中,当属Mocha最适合Node.js测试。
作为一个开源的测试运行程序,Mocha提供了一种易于编程的程序化方法,来测试并获取结果。在与数据库一起使用时,我们可以通过Mocha,将真实或虚拟值提供给测试用例,以进行全面的Node.js测试。
7.测试覆盖率
通常,测试覆盖率可用于评估测试用例所覆盖的代码量,因此它也是我们在编写测试时的一项重要指标。为了保证在编写Node.js测试用例时,能够获得良好覆盖率,我们除了了解目标应用的基本性质与功能,还应该从成本增加的角度,谨慎考虑哪些需要被添加到测试范围中。例如,对于实时且具有高度交互特点的应用,我们应当保证测试的覆盖率尽量达到100%,以获得全面的测试结果。为此,您可以选用Istanbul测试覆盖率工具,以实现与Mocha的良好集成。
8.用插件提高测试覆盖率
为了避免由于某种原因所导致的任何失败或测试被跳过,我们可以通过添加插件,来最大程度地提高代码测试的覆盖率。同时,它们可以共享测试成败的相关报告,以减少原有测试的误报率。
9.分析测试覆盖率报告
如前文所述,我们可以通过将Mocha和Istanbul相结合,以生成简单、直接、实用的测试覆盖率报告。而通过对报告深入分析,开发人员则能够查找出故障的根源,进而着手修复。
10.标注测试用例
不同的测试用例往往侧重于不同的场景和需求。我们需要根据使用情况,将它们分门别类。当然,由于某些测试可能会横跨多个组类,因此最好的方法便是对测试用例进行标注。例如我们可以分配:冒烟(smoke)测试、I/O测试、健全(sanity)测试,端到端(e2e)测试等标签。据此,我们可以快速分清,哪些测试用例是真正适合目标应用的。
11.变异测试
有时候,测试人员需要使用一些虚拟数据或模拟数据,来通过调整应用程序的逻辑与行为,以定位程序代码的缺陷。对此,我们可以事先定义好相关变异操作,例如:使用错误的操作符或变量名,来模拟典型的应用错误。此举有时也被称为“植入错误”,以查看开发出的代码逻辑在意外情况下,将如何做出反应。在自动化Node.js测试中,此类测试往往能够让开发人员在极端问题出现之前,予以处理和解决。Stryker是该领域最受欢迎的代码库,建议您将其添加到常用Node.js测试工具列表中。
12.非剽窃(Non-Plagiarised)测试
有时候,开发人员可能会直接从互联网上复制一段代码,并将其运用到正在开发的软件应用中。不过,他们不会意识到该代码可能已经被许可给了其他公司。由此引发的版权问题,很可能会导致严重的法律纠纷。因此,在使用Node.js时,检查“剽窃”是非常常见的做法。我们可以通过安装以下软件包,来实现:node.js npm plagiarism-checker。具体安装与使用步骤如下--
1. 安装:npm i plagiarism-checker
2. 请添加以下内容,以使用该代码库:
- var a = require('plagiarism-checker');
- var b = new a();
- var config = b.getConfig();
3. 从链接--https://www.npmjs.com/package/plagiarism-checker处,下载剽窃检查器的代码。
4. 在安装如下依赖项后,将其添加至项目中:
- $ npm install lodash
- $ npm install request
- $ npm install request-promise
- $ npm install mime-types
13.提供逻辑输入
对于自动测试用例,测试人员有时会倾向于,将各种与实际情况相去甚远的随机值作为输入,其结果往往无法评估出确切的效果与性能。因此我们应当始终采用与现实生活场景相切合的近似实际输入,来测试应用的真实水准。在此方面,Faker库能够通过与Node.js的完美结合,生成大量实时的输入数据,以产生相对真实的结果。
同理,我们不应只用少量的输入去浅尝辄止,而需要通过大量丰富的输入数据集,来全面检验Node.js应用的各种逻辑与功能。例如,对于那些将城市名称作为输入参数的函数,有效的测试数据应当是新德里、孟买、伦敦、纽约等,而不是诸如abc、xyz等毫无意义的随机值。
14.使用应用代码校验(Lint)
通常,我们将可用于检查整个代码,并针对任何编程错误、代码样式问题、以及可疑结构,发出警告的工具称为Linter或Lint。在针对Node.js应用开展测试时,我们可以使用linters来捕获,那些潜藏在程序逻辑之后的代码结构性错误,其中包括未声明的变量分配、未定义的变量使用、以及语法格式错误等。ESLint(https://eslint.org/)便是此类可与Node.js相集成,并能遵循自动化规范的工具。它可以在修复各种问题的同时,让目标代码更加易于阅读和理解。
15.基于属性的测试
此类测试可用于检查功能和程序的各项属性。目前,可用于自动执行基于属性的测试工具包括:fastCheck,Mocha Test Check和QuickCheck。它们的主要优势在于:
- 拥有广泛的输入类型范围,可生成大量有效的测试数据和测试用例集。
- 通过长时间运行某个功能函数的属性类输入,以协助检查其阈值。例如,对于某个仅接受两个参数输入的函数而言,其规则是其中一个参数必须为偶数值。那么我们在采用基于属性的测试时,便可以检查其接受各种奇、偶数组合输入后的反应。
16.用Chai来断言
如前所述,断言有助于我们将实际结果与预期结果进行比较,以判定测试用例在某些意外错误、或已知的逻辑流程变更时,是否能到达预期的效果。在使用Node.js自动化测试时,Chai库就能够通过预期断言和分析结果,在无需花费更多时间进行挖掘的情况下,节省团队可用于修复的资源和精力。下面是Chai断言的一个示例:
- expect(‘a’).to.not.have.property(‘b’);
17.测试异常(Exceptions)
在编写测试时,我们自然而然地会将重点放在那些提供良好代码覆盖率的测试用例和方案上,而忽略了为这些用例添加可验证的各种异常信息,并导致运维人员无法跟踪应用抛出的错误。当然,一些大型组织为此会用到“混沌测试”。此外,我们还可以采取如下两个处置方式:
- 在出现错误时,立即终止服务器的各项功能,转为测试和评估服务的稳定性、性能、以及对于整体系统的影响。
- 从服务器端强制传递出不同的响应代码,并检查应用程序的行为。
18.测试金字塔
测试金字塔是一个三层结构的三角形。如下图所示,每一层都定义了不同的测试阶段与方法。我们可以根据产生的成本和执行的速度进行分类,其顶点表示成功最高,但最快的测试。
金字塔的底层包括了独立的基本功能和单元测试。中间层的集成测试,可方便用户以彼此整合的方式,测试不同的模块。顶层是前端与用户界面测试,我们可以使用诸如LambdaTest等先进的自动化工具来完成。显然,单元测试最慢,而由于模块级分布较少,因此前端测试最快。
19.分别测试每个应用组件
分别测试每个模块或组件的功能,有时也被称为组件测试。它可以根据不同的输入,来验证被测模块的响应情况。与单元测试相比,组件测试具有良好的覆盖率和更快的速度。在上述金字塔测试中,我建议您在完成单元测试后,再使用组件测试,以获得更好的结果,并能发现更多的未知问题。
20.检测基础架构问题
在自动化测试过程中,测试人员最容易犯的一个错误是:只测试了应用程序的功能,以及关注到了测试覆盖率,而忽略了由基础架构所导致的,各种与实时负载和实际场景相关的问题。其中,最常见的基础架构问题包括:内存过载、服务器突然关闭、以及API响应延迟等方面。它们都会显著地影响到应用的正常行为与服务的提供。
21.并行测试
通常,我们的传统测试流程是:执行一个用例,等待其结果,对其进行分析,提供反馈意见,执行下一个测试,周而复始。开发团队需要对所有测试的运行结果,逐一予以反馈和解决。显然,这种串行方式不但增加了团队成员的工作量,并且可能导致不必要的返工。
而并行测试则能够让团队同时执行多个用例。他们既能一次性获取待分析的报告,进而共享与合并待处理的反馈。对此,整个团队可以使用前文提到的Mocha之类的并行测试工具,为Node.js的自动化测试大幅减少反馈的层级,并且能够在更短的时间内协同解决问题,进而为公司节省了大量的时间和资源。
22.保持依赖关系的更新
为了有效地开展测试,并获得准确的结果,我们需要通过各种手动的方式,来保证各种依赖项和库的更新,进而防止未知错误的出现。不过,为了避免可能发生的人为错误,我们往往可以通过工具,定期检查是否有最新的版本出现,并对任何依赖项的新版本触发自动更新。
23.在Selenium Grid上执行跨浏览器测试
作为一个易用的开源类跨浏览器测试工具,Selenium附带有许多实用的程序,以满足不同的测试需求。为了消除对浏览器数量的限制,我们可以使用Selenium Grid的云端应用,以提供更多的浏览器和更多不同的配置。
小结
总的说来,为了使用Node.js来实现一套稳定、有效的自动化测试框架,您可以有选择性地参考上述讨论的23种优秀实践,以保证开发和测试的质量与效果。
原文标题:23 Node.js Best Practices For Automation Testing,作者:Rahul Jain
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】