最好用的JavaScript测试框架大盘点
Posted 前端之巅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最好用的JavaScript测试框架大盘点相关的知识,希望对你有一定的参考价值。
这篇文章将列出 javascript 测试方面最重要的工具,它融合了很多来自其他优秀文章的信息,并增加了我们多年来为不同产品实施不同测试解决方案的经验总结。
jsdom 是 WHATWG DOM 和 html 标准的 JavaScript 实现,只使用普通的 JS 来模拟浏览器环境。
在这个模拟的浏览器环境中,可以非常快速地运行测试。jsdom 的缺点是不能在真实的浏览器之外模拟所有东西(例如不能截取屏幕截图),所以它会限制你的测试范围。
值得一提的是,JS 社区正在对它做出改进,当前版本非常接近真实的浏览器。
Istanbul 将告诉你单元测试涵盖到了多少代码。它将以百分比的形式告诉你语句、代码行、函数和分支的覆盖率,你可以更好地了解还剩下哪些东西没有被覆盖到。
https://karma-runner.github.io/2.0/index.html
Karma 允许你在浏览器和浏览器模拟环境(如 jsdom)中运行测试。
Karma 提供了一个带有特殊页面的测试服务器,以便在页面环境中运行测试。这个页面可以在很多浏览器上运行。
这也意味着也可以使用 BrowserStack(https://www.browserstack.com/)之类的服务来远程运行测试。
Chai 是最受欢迎的断言库。
https://github.com/unexpectedjs/unexpected
Unexpected 是一个断言库,语法与 Chai 略有不同。它也是可扩展的,因此基于它的库的断言会更加高级,例如 unexpected-react(https://github.com/bruderstein/unexpected-react)。
Sinon 是一个非常强大的独立测试工具,用于创建 stub 和 mock,适用于任何 JavaScript 单元测试框架。
https://github.com/testdouble/testdouble.js
testdouble 是一个相对没有那么流行的库,可以完成 Sinon 所做的事情,并声称可以做得更好。它在设计、理念和功能方面存在一些差异,在很多情况下,这些差异会很有用。
Wallaby 是另一个值得一提的工具。它不是免费的,但很多用户会建议购买它。它可以在你的 IDE 中运行(它支持所有主要的 IDE),会在你写代码时运行测试,实时地告知你是否出现了错误。
https://github.com/cucumber/cucumber-js
Cucumber 可用于编写 BDD(行为驱动开发)测试用例,测试用例分为基于 Gherkin 语法的接受标准文件和与之对应的测试。
测试可以用框架支持的各种语言编写,包括 JS:
Feature: A reader can share an article to social networks
As a reader
I want to share articles
So that I can notify my friends about an article I liked
Scenario: An article was opened
Given I'm inside an article
When I share the article
Then the article should change to a "shared" state
module.exports = function() {
this.Given(/^I'm inside an article$/, function(callback) {
// functional testing tool code
})
this.When(/^I share the article$/, function(callback) {
// functional testing tool code
})
this.Then(/^the article should change to a "shared" state$/, function(callback) {
// functional testing tool code
})
}
很多团队发现这种语法比 TDD 更方便。
Mocha 是目前使用最多的库。与 Jasmine 不同,它需要与第三方断言、mock 和 spy 工具(通常是 Enzyme 和 Chai)一起使用。
因此 Mocha 用起来有点麻烦,也难以分成更多的库,但它更灵活、更容易扩展。
例如,如果你需要特殊的断言逻辑,可以 fork 一个 Chai,并使用自己的断言库替换 Chai 中的断言库。在 Jasmine 中也可以这么做,但在 Mocka 中,这种变化会更加明显。
社区——有很多插件和扩展用于测试独特的用例。
可扩展性——很多插件、扩展和库,如 Sinon,它包含了 Jasmine 所没有的功能。
全局对象——默认情况下创建测试结构全局对象,但显然不是 Jasmine 中的断言、spy 和 mock。
Jest 是 Facebook 推荐的测试框架。它是基于 Jasmine 的,我们稍后会介绍 Jasmine。截至目前,Facebook 替换了 Jest 的大部分功能,并在其上添加了很多新功能。
Jest 的速度和便利性给人们留下了印象深刻。
性能——首先,Jest 实现了并行测试机制,被用在具有很多测试文件的大型项目上时速度更快。
UI——既清晰又方便。
随时可用——提供了断言、spy、mock,可以完成 Sinon 能够完成的所有事情。
全局对象——就像 Jasmine 一样,它默认创建测试全局对象。不过这也有不好的一面,因为它会降低测试的灵活性和可控性,但在大多数情况下,它会让你的工作变得更轻松:
快照测试——jest-snapshot(https://github.com/facebook/jest/tree/master/packages/jest-snapshot)由 Facebook 开发和维护,可以被用在任何其他框架中,作为框架集成工具或插件的一部分。
改进的模块模拟——Jest 提供了一种模拟大型模块的简便方法,用以提高测试速度。例如,可以模拟服务来解析 promise,而不是真的发出网络请求。
代码覆盖——内置了一个基于 Istanbul 的代码覆盖率工具。
可靠性——虽然这是一个相对年轻的库,但经过一两年的沉淀,现在基本稳定,目前所有主要的 IDE 和工具都支持它。
开发—— jest 只更新发生变更的文件,因此在 watch 模式下的运行速度非常快。
Jest 就是基于 Jasmine 构建的。为什么需要使用 Jasmine?它已经存在了很长时间,社区写了很多有关它的文章,开发了很多与它有关的工具。
此外,Angular 仍然建议使用 Jasmine,而不是 Jest,尽管 Jest 也非常适合运行 Angular 测试,很多人也都这么做了。
随时可用——提供了测试所需的一切。
全局变量——提供了全局作用域内所有重要的测试功能。
社区——它从 2009 年就出现在市场上,现在有大量围绕它的文章、最佳实践和工具。
Angular——Angular 官方文档中建议使用 Jasmine。
Ava 是一个简单的测试库,可以并行运行测试。
随时可用——提供了测试所需的一切。
全局对象——它不会创建任何测试全局对象,因此你可以更好地控制测试的运行。
简单——简单的结构和断言,无需复杂的 API,同时支持很多高级特性。
开发—— Ava 只更新发生变更的文件,在 watch 模式下可以加快运行速度。
速度——作为单独的 Node.js 进程并行运行测试。
快照测试——作为框架的一部分。
Tape 是这些框架中最简单的一个,它只是一个使用 Node 运行的 JS 文件,提供了“切中要害”的 API。
简单——没有复杂的 API,只有简约的结构和断言。
全局对象——不创建任何测试全局对象,因此你可以更好地控制测试运行。
测试之间不共享状态——Tape 不鼓励使用“beforeEach”之类的功能来确保测试的模块化以及最大限度地控制测试周期。
不需要 CLI——Tape 可以在任何可以运行 JS 的地方运行。
https://github.com/SeleniumHQ/selenium
Selenium 通过自动化浏览器来模拟用户行为。它不是专门针对测试而开发的,我们可以用它来实现多种用途。
我们可以通过多种方式、使用各种编程语言来控制 Selenium,某些工具甚至不需要写代码。
在 JavaScript 测试方面,通过 Selenium WebDriver(http://seleniumhq.github.io/selenium/docs/api/javascript/index.html)来控制 Selenium 服务器,将其作为 NodeJS 和操作浏览器的服务器之间的通信层。
Node.js <=> WebDriver <=> Selenium Server <=> FF/Chrome/IE/Safari
WebDriver 可以被导入到测试框架中,然后编写测试代码:
describe('login form', () => {
before(() => {
return driver.navigate().to('http://path.to.test.app/')
})
it('autocompletes the name field', () => {
driver
.findElement(By.css('.autocomplete'))
.sendKeys('John')
driver.wait(until.elementLocated(By.css('.suggestion')))
driver.findElement(By.css('.suggestion')).click()
return driver
.findElement(By.css('.autocomplete'))
.getAttribute('value')
.then(inputValue => {
expect(inputValue).to.equal('John Doe')
})
})
after(() => {
return driver.quit()
})
})
Apium 提供了类似于 Selenium 的 API,可以使用以下工具在移动设备上测试网站:
ios 9.3+,Apple 的 XCUITest:
https://developer.apple.com/reference/xctest
在 iOS 9.3 之前,Apple 的 UIAutomation:
https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/
android 4.2+,谷歌的 UiAutomator/UiAutomator2:
http://developer.android.com/tools/help/uiautomator/index.html
Android 2.3+,谷歌的 Instrumentation:
http://developer.android.com/reference/android/app/Instrumentation.html
Windows Phone,微软的 WinAppDriver:
http://github.com/microsoft/winappdriver
如果你在使用 Selenium 或基于 Selenium 的工具,你也可以使用 Apium 在移动设备上测试网站。
Protractor 对 Selenium 的库进行了包装,为 Angular 添加了一个改进的语法和特殊的 hook。
Angular——提供了特殊的 hook,当然也可以与其他 JS 框架一起使用。Angular 官方文档建议使用这个工具。
错误报告——良好的机制。
支持——支持 TypeScript,该库由 Angular 团队负责运营和维护。
WebdriverIO 提供了自己的 selenium WebDriver 实现。
语法——非常简单易读。
灵活性——一个简单可将扩展的库。
社区——它得到了开发者社区的热情支持,社区提供了大量的插件和扩展。
Nightwatch 也提供了自己的 Selenium WebDriver 实现,以及自己的测试框架,包括测试服务器、断言和工具。
框架——可以与其他框架一起使用,而且如果你希望单独运行功能测试,它可能会特别有用。
语法——看起来最简单,最易读。
支持——不支持 TypeScript,这个库似乎比其他库获得支持稍微少一些。
TestCafe 是基于 Selenium 的工具之外的另一个绝佳选择。它在 2016 年底经过重写并开源。
它还有一个付费版本,提供了不需要编程的测试工具,比如测试记录器和客户支持。这点很重要,因为很多过时的文章错误地认为它是闭源的,并将其视为它的一个不足。
它将自己作为 JavaScript 脚本注入到网页中,而不像 Selenium 那样控制浏览器本身。因此,TestCafe 可以运行在任何浏览器中,包括移动设备,并且可以完全控制 JavaScript 的执行周期。
TestCafe 现在正处于大规模发展阶段,尽管它已经很稳定,并且功能也是齐全的。
快速设置——你只需要打开任何一个浏览器就运行测试。
跨浏览器和设备——支持很多浏览器和设备,可以与 SauceLabs 或 BrowserStack 一起使用,并在 Headless Chrome 和 Headless Firefox 中运行测试。
并行测试——TestCafe 可以同时在多个浏览器实例上运行测试,这可以显著缩短测试时间。
方便的错误报告。
自己的生态系统——TestCafe 使用自己的测试结构。它可能非常方便,因为 UI 测试通常与其他测试分开运行。
import { Selector } from 'testcafe';
fixture `Getting Started`
.page `https://devexpress.github.io/testcafe/example`
// Own testing structure
test('My first test', async t => {
await t
.typeText('#developer-name', 'John Smith')
.click('#submit-button')
.expect(Selector('#article-header').innerText)
.eql('Thank you, John Smith!')
})
Cypress 是 TestCafe 的直接竞争对手。它们做的事情比较相似,即将测试注入到网页中,提供更现代、更灵活和方便的测试方式。
Cypress 刚从内部测试转到公开测试(在 2017 年 10 月份),不过它们已经有很多采用者。
没有跨浏览器支持——现在只支持 Chrome(而且不是 headless 模式)。
缺乏高级功能——与 TestCafe 相比,仍然缺失平行测试和其他一些测试工具,但开发团队的产品路线图中包含了更多功能。
文档——翔实而清晰。
调试工具——容易调试和日志记录。
使用 Mocha 作为它的测试结构,这样你的 UI 测试与其他测试使用的是相同的结构,看起来更“标准”。
describe('My First Cypress Test', function() {
it("Gets, types and asserts", function() {
cy.visit('https://example.cypress.io')
cy.contains('type').click()
// Should be on a new URL which includes '/commands/actions'
cy.url().should('include', '/commands/actions')
// Get an input, type into it and verify that the value has been updated
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
})
})
https://github.com/GoogleChrome/puppeteer
Puppeteer 是一个由谷歌开发的 Node.js 库。它提供了一组方便的 Node.js API 来控制 Headless Chrome。
Headless Chrome 其实也就是 Chrome v59+,可以通过 --headless 标记启动。当 Chrome 以 headless 模式运行时,它会公开一组 API,用来控制它自己,而 Puppeteer 是谷歌提供的用于控制 Chrome Headless 的 JavaScript 工具。
值得一提的是,Firefox 也在 2017 年底发布了 headless 模式。
请注意,其他一些测试工具也可以用来控制 Headless Chrome 和 Headless Firefox。例如:TestCafe、Karma。
Puppeteer 相对较新,但它已经有一个庞大的支持社区。
由于它是原生的,所以速度更快,并使用了最新的 Chrome 引擎,不像 PhantomJS 是基于 WebKit 的旧分支构建的。
Headless Chrome(Puppeteer 也是)的一个主要缺点是不支持 Flash 这样的扩展,在未来可能也不会支持。
Phantom 实现了 chromium 引擎,用来创建可控的类似 Chrome 的 headless 浏览器。
在谷歌发布 Puppeteer 之后,Phantom 的创建者和维护者 Vitaliy Slobodin 离开了这个项目,因此自 2017 年中期以来它的维护和开发速度要慢得多,尽管仍然有在维护。
那么,为什么你会使用 Phantom 而不是 Puppeteer ?
首先,因为它更加成熟,有很多很好的指南和工具。
它也被 CasperJS 等很多有用的工具所使用。
它使用较旧的 WebKit,因此可以模拟较旧的 Chrome 浏览器。
此外,Phantom 支持 Flash 等扩展。
Nightmare 是一个很棒的 UI 测试库,它提供了一个非常简单的测试语法。
Nightmare 使用了与 Phantom 类似的 Electron,但 Electron 使用了更新的 Chromium,维护更加积极,因为 Electron 的主要目的是使用 JavaScript、HTML 和 CSS 构建跨平台的桌面应用程序。
下面是 Nightmare 代码与 Phantom 代码的区别。
yield Nightmare()
.goto('http://yahoo.com')
.type('input[title="Search"]', 'github nightmare')
.click('.searchsubmit')
Casper 是在 PhantomJS 和 SlimerJS(与 Phantom 类似,只是使用了 Firefox 的 Gecko)基础上开发的,提供了导航、脚本和测试实用程序,并在创建 Phantom 和 Slimer 脚本时抽象出了很多复杂的异步内容。
Slimer 已经被广泛使用了很长一段时间,虽然被认为是实验性的,但在 2017 年底发布了测试版 1.0.0-beta.1,使用了新的 Headless Firefox,目前正在努力使版本稳定并发布 1.0.0。
Casper 可能会在不久的将来(2.0 版本中)从 PhantomJS 迁移到 Puppeteer,并成为测试 Headless Chrome 和 Headless Firefox 的绝佳工具。
https://github.com/codeception/codeceptjs/
与 CucumberJS 一样,Codecept 对不同库的 API 进行了另一种抽象,让你可以在测试时更多地专注于用户行为。
它看起来是这样的:
Scenario('login with generated password', async (I) => {
I.fillField('email', 'miles@davis.com');
I.click('Generate Password');
const password = await I.grabTextFrom('#password');
I.click('Login');
I.fillField('email', 'miles@davis.com');
I.fillField('password', password);
I.click('Log in!');
I.see('Hello, Miles');
});
你可以使用这段代码执行这些库(之前都介绍过):WebDriverIO、Protractor、Nightmare、Appium、Puppeteer。
如果你认为这种语法更符合你的需求,可以尝试一下。
英文原文:
https://medium.com/welldone-software/an-overview-of-javascript-testing-in-2018-f68950900bc3
以上是关于最好用的JavaScript测试框架大盘点的主要内容,如果未能解决你的问题,请参考以下文章
盘点 VS Code 常用插件!选择最好用的插件,还你不一样的编译器