JavaScript测试自动化的基础

这是“Dip Advent Calendar”的第三天。
※在“转码器”一节中增加了有关ECMAScript的附注。(12/5)

摘要

我通常负责后端开发,并最近开始学习JavaScript的自动化测试。
因此,我想与那些与我一样初学JavaScript自动化测试的人分享我在建立整个环境时学到的内容。
为了基本理解,我主要会写下有关引入前提知识的内容。

JavaScript测试自动化的特点

特别明显的亮点是其中具有许多构成要素。
在网络上寻找文章时,可以找到许多标题为“使用○○、▲▲、□□和◆◆的JavaScript自动化测试!”之类混合各种要素的文章。
对于这些文章,如果没有相关知识,就无法理解“○○”和“▲▲”代表什么,可能会看起来像一些莫名其妙的味道(比如蔬菜叠成的山药味高浓巧克力拿铁)。
因此,接下来将对这些莫名其妙的味道的构成要素进行解释说明。

测试自动化的组成要素

1. 测试框架

我相信大家都已经知道这个内容,但还是重新写一遍。

我們需要寫測試代碼來進行測試自動化。
然而,在沒有任何工具的情況下,撰寫測試代碼會耗費大量的精力。
例如,假設有一個函式用於執行加法運算,

function add(x, y) {
  return x + y;
}

假设要自己编写对此的测试代码。

if(add(1, 2) == 3) {
  console.log("テスト結果OK");
} else {
  console.log("テスト結果NG");
}

在某种情况下,可能会陷入不断编写低级代码的困境。(这只是一个极端的例子)
而且,目前情况下测试执行后的结果非常难以理解。
不知道哪些测试成功了或失败了,总共有多少个测试,有多少个通过了。
又或者在失败的情况下,是哪个部分出了问题。

为了解决这些问题,存在一种被称为测试框架的工具。
比如在Java中是JUnit,在Ruby中是RSpec,在PHP中是PHPUnit或者PHPSpec等等。

RSpecの実行結果

考试的结果、实施内容和有争议的内容都被详细输出了。

关于这个测试框架,JavaScript自然也有相关的选项。
常见的有Mocha和Jasmine。
通过使用这些测试框架,您可以在JavaScript中高效地编写测试。

※测试框架的好搭档之一(测试替身)

这是一个很方便的测试框架,但是在一些特殊情况下会遇到无法涵盖的问题。
举个例子,假如我们想要测试一个被函数funcA()调用的另一个函数funcB(),并确保它被正确调用的复杂情况,仅仅使用Mocha是无法很好地进行测试的。

function funcA() {

  // 色んな前処理前処理
  // ここでarg1からarg3までが用意される
  ...

  funcB(arg1, arg2, arg3);  // ← ここで適切なパラメータが渡されるか確認したい

  ...
  // 後処理
}

作为解决这类测试用例的工具,存在着一种称为“测试替身”的东西。
使用这个测试替身,可以在上面提到的例子中,为funcA()引入一个扮演funcB()的影武者,并且通过操控这个影武者来确认funcB()是如何被调用的。

在使用Mocha作为测试辅助工具时,可以使用一个名为Sinon.js的测试替身工具。它经常在包含Mocha的代码中出现,所以记住它会很有帮助。
※Jasmine则已经默认包含了测试替身的功能。

※测试框架的伴侣之二(断言库)

测试框架的作用之一是可以将测试结果以易读的方式输出。
作为具有专注于测试结果输出功能的工具,有一种被称为断言库的东西。
在前面提到的Mocha中,可以通过使用这个断言库来扩展测试结果的可读性。
著名的断言库包括power-assert(power-assert.js)和Chai。
特别是在使用Mocha时,很多情况下会同时使用power-assert,所以记住这个会很有用。


总结至此

    • テスト自動化をするためにはテストコードを書かねばならない

 

    • テストコードを効率良く書くため、テストフレームワークが存在する

 

    • JavaScriptではMochaやJasmineというテストフレームワークがある

 

    Mochaを使う場合は、Sinon.jsやpower-assertなども併せて使うと良い

哇,似乎可以准备一些可以编写测试代码的商品了!只需要详细调查每个商品并编写测试代码就可以了!真是太好了。

请用中文将以下内容进行释义:

• You should always follow your dreams and never give up, no matter how difficult the journey may be.

• It’s important to take care of your physical and mental well-being in order to lead a happy and fulfilling life.

• Learning from failures and mistakes is a valuable experience that can ultimately lead to success in the future.

是的,如果您是一个有洞察力的人,您可能已经注意到了。
确实,感觉您可能可以写测试代码,但是…

这段测试代码在哪里执行?

是的。

就像之前提到的RSpec和PHPUnit一样,它们分别是在Ruby和PHP上运行的,因此可以通过在终端上输入命令来执行。

能够通过命令执行意味着可以在CI工具等中轻松调用。

那么,JavaScript的情况会怎样呢。

在Web应用程序中,JavaScript的运行环境是用户的浏览器。
如果要在浏览器中执行,该如何加载测试代码呢?
即使使用所谓的浏览器内置开发工具,也需要手动准备吗?
这样一来,是否可以说测试无法自动化了呢?

一股可疑的氛围笼罩着。
然而,在开头出现的谜之咒语中,包含了这些问题的解决方法!
因此,接下来就进入了这个可以说是正片的JavaScript测试代码执行平台的讨论。


2. JavaScript执行环境

这也是因为它很有名,所以我不太想再重复写一遍…
在进行测试自动化时,我们需要在浏览器以外的地方运行JavaScript。
而众所周知,JavaScript的执行基础是NodeJS。
没有必要再进行再次解释了。它是服务器端JavaScript的功臣。
在进行JavaScript的测试自动化时,我们隐含地使用了NodeJS。(还有其他原因,但会在后面提到)

3. 源码转译器 qì)

在使用NodeJS进行测试时,有一个很大的问题。
原来在浏览器上运行的代码,很多时候不能在NodeJS中正常运行。

举个简单的例子,比如我们使用jQuery等外部库的情况。
如果想在浏览器上正常运行,那么要如何加载外部库呢?
我们可以在HTML上使用这样的脚本标签来加载外部库对吧。
然而在NodeJS中,我们直接执行JavaScript代码,不能使用这种标签来加载外部库。
那么,我们应该如何加载外部库呢?

实际上,在JavaScript中,提供了用于加载外部库的import/export语法。如果要在NodeJS等环境中加载外部库,可以使用它来解决问题。因此,在进行NodeJS测试时,需要将目标代码中的import/export进行重写。

然而,这里又出现了问题。
就是关于导入/导出的功能,在目前的阶段下任何浏览器都没有实现。
换句话说,目前没有任何浏览器支持导入/导出的功能。

    • ブラウザで動くコード → NodeJSで動かない

 

    NodeJSで動くコード → ブラウザで動かない

我被困住了。

突然发现,确实有一个解决这个问题的救世主。那就是转译器。

转换器是指将一个程序源代码转换为具有相同行为的另一个程序源代码的工具的总称。
借助这个转换器,可以将在测试执行后运行在NodeJS上的代码转换为在浏览器上运行的代码。
在JavaScript转换中,Babel、webpack和Browserify等工具非常有名。

※ 有关JavaScript的编写方式

我之前提到了在浏览器中无法运行import/export的问题。
我认为大家可能都遇到过想使用的语言功能在环境中不受支持的情况。
经常见到的原因之一是,安装的版本在执行环境中可能比较旧。
哇,这个服务器居然还在使用PHP 4的版本,真让人吃惊…

哎呀,请稍等一下。
JavaScript的版本是怎么样的呢?
JavaScript到底是由哪里的谁来制定语言规范的呢?

似乎在这方面经历了一些波折,但目前被称为事实标准的规范由一个名为Ecma International的团体确定。这个团体通过ECMAScript这个名字将其标准化,并且存在着ECMA 2015(又称为ES6)和ECMA 2016等版本。新版本的ECMAScript支持使用类(!),但很遗憾,目前的浏览器还不支持这个功能。

哎呀,这个情况好像和刚才讲Node.js时一样。

所以,你应该已经明白,我们将使用一个转译器。
通过此转译器,可以将基于ECMA2015等编写的JavaScript代码转换成可以在浏览器上运行的代码。
因此,即使在想使用最新酷炫规范编写JavaScript的情况下,也会使用转译器。

4. 浏览器(和,任务执行器)

我知道有些人可能会纳闷为什么刚刚切换到NodeJS,现在又提到了浏览器。但请仔细考虑一下,NodeJS直接执行JavaScript代码。那么在普通的浏览器中会发生什么呢?通常情况下,浏览器会加载HTML文档,并将其中的JavaScript作为一个元素执行。但在NodeJS中,无法对这个文档(即DOM)部分进行测试。(不过,使用模块的话还是可以实现的)。前端的JavaScript经常会涉及到改变文本颜色、启用按钮等修改DOM的操作。为了测试这些行为,当然最好的方法是在实际的浏览器中运行。

然而,当然不会傻到自己打开浏览器…什么胡说八道的事情都不会做。
可以通过命令启动,并自动进行测试执行。
这时候使用任务执行器就很方便了。

可以列举一些著名的任务执行器,比如Karma和gulp。
借助这些Karma和gulp,可以将测试目标代码加载到浏览器中,并自动执行测试。
顺便提一句,Karma和gulp是在NodeJS中运行的。
(前面提到的,将NodeJS嵌入其中的原因就在这里)。

此外,如果只是在考试中使用的话,不需要特意使用外观豪华的浏览器才行。
在这种情况下,有一种非显示页面的浏览器,被称为无头浏览器,非常方便。
其中一个著名的例子是PhantomJS。
在任务运行器中,可以选择要使用的浏览器,所以选择PhantomJS也是一个不错的选择。

总结

测试框架

    • Jasmine

 

    Mocha

测试双倍

    SinonJS

断言库 kù)

    • power-assert

 

    Chai

JavaScript执行环境

    NodeJS

转译器

    • Babel

 

    • webpack

 

    Browserify

JavaScript语言规范

    • ECMA 2015(ES6)

 

    ECMA 2016

任务执行器

    • Karma

 

    gulp

无头浏览器

    PhantomJS

最后

我写了很长一段时间,但是你觉得怎么样呢?
我只是作为一个开始写的,所以没有详细介绍具体的开始步骤和使用方法。
实际的开始步骤和结构等,我会提供一些参考链接,希望你能参考那里。
希望你能轻松地阅读链接中的文章。

如果文章中有错误,请在评论中指出。

请参阅以下链接。

■ 引入测试到前端
整理了包括实际的代码在内的引入测试的流程。

■ 用Karma + PhantomJS + Mocha + power-assert搭建了客户端JS的单元测试环境
已经发布了实际搭建的测试自动化环境。
如果你读了这篇文章后,我想你应该能理解标题中的咒语是什么意思了,你觉得怎么样?

只需要一种选择:
■ 从零开始的JavaScript生活
不仅限于测试自动化,您还可以了解最近JavaScript开发环境中的工具。

广告
将在 10 秒后关闭
bannerAds