资讯专栏INFORMATION COLUMN

[译] 如何为 Vue 项目写单元测试

svtter / 500人阅读

摘要:在这个教程中,我们将创建一个简单的项目,并为其写一个简单的单元测试。希望你读这些代码的时候思路能够清晰,不过它对于刚刚开始接触单元测试的人来说可读性并不是很高。总结在日常工作以及开发中,尤其是项目,测试是非常重要的。

译者:明非

链接:https://fanmingfei.com/posts/A_Vue_Unit_Text_Tutorial.html

原文:https://scotch.io/amp/tutorials/how-to-write-a-unit-test-for-vuejs?from=timeline&isappinstalled=0

众所周知,Vue.js 是一个非常牛逼的 JavaScript 框架,对于创建复杂功能的前端项目是非常有用的。不管是什么项目,检查应用是否正常工作,运行是否为预期,是尤为重要的。然而,为了保证业务正常运行,我们的项目,每做一次更新,都要对所有功能做一次回归测试,随着项目的增大,重复的测试工作越来越多,越来越乏味,手工测试将变成一个恶心的事情。正因如此,自动化测试诞生了,它可以随时监测我们的代码是否正常工作,运行结果是否符合预期。在这个教程中,我们将创建一个简单的VueJS项目,并为其写一个简单的单元测试。

我们创建一个基本的 to-do list 组件进行测试。我们将要测试的是,列表展示是否正确,用户是否可以正常添加到 to-do list。通过这个教程,你将学会如何去为你的组件写一个测试,测试包括HTML展示是否正确以及用户的操作是否能正常进行。

这个git库是这篇文章的所有代码。

创建项目

创建 JavaScript 项目可能是一个复杂的过程。琳琅满目的依赖库供我们选择。不过还好,我们可以使用vue-cli来创建VueJS项目,它帮我们包办一切。运行 npm install 来安装依赖:

npm install -g vue-cli
vue init webpack project-name

在这个过程中,你可能会遇到几个提示。大多数提示比较简单易懂,你可以直接选择默认选项。需要注意的是,我们需要是否安装 vue-routerKarmaMocha的提示后输入YES来引入这些工具。然后开始安装依赖:

cd project-name
npm install

接下来我们执行下面的命令,这个命令将会在本地运行你的应用并在浏览器中打开。

npm run dev

如果你的网络好的话,一会就装好了。

依赖

Webpack (2.3) 是一个打包器,它可以合并打包JavaScript,CSS,HTML文件,并且提供给应用运行。Bable (v6.22) 是一个编译器,用来把ES6编译成ES5。目前有很多 JavaScript 标准在许多浏览器中还没有被支持,所以需要将ES6转成ES。

测试依赖

Karma (v1.4) 是一个运行时,它产生一个 Web 服务环境来运行项目代码,并且执行测试。Mocha (v3.2) 是一个 JavaScript 测试框架。Chai (v3.5) 是一个 Mocha 可以使用的断言库。

在你的项目中,你可以找到下面这些目录:buildconfignode_modulessrcstatictest。对于本教程来说最重要的是src,它包括我们应用的代码,用来测试。

第一次测试

从最基本的开始去做一般都没错。我们将从创建简单的列表组件开始。在 src/components 里创建一个新文件叫做 List.vue 并且将下面代码写进去。



在这个组件中,列表项被储存在数组(listItems)里面。数据被传递到模板,然后被遍历(v-for),然后展现在页面上。

当然,我们需要看到刚刚创建的列表,我们可以创建一个新的路由来展示这个组件。在src/router/index.js中创建一个路由,添加完了代码应该是下面这样的:

import Vue from "vue"
import Router from "vue-router"
import Hello from "@/components/Hello"
import List from "@/components/List"

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: "/",
      name: "Hello",
      component: Hello
    },
    {
      path: "/to-do",
      name: "ToDo",
      component: List
    },
  ]
})

现在,访问localhost:8080/#/to-do,可以看到我们做的应用。

首先,我们要测试的是数据的正确性。在test/unit/specs目录下创建一个List.spec.js,并且写入下面的代码:

import List from "@/components/List";
import Vue from "vue";

describe("List.vue", () => {

  it("displays items from the list", () => {
      // our test goes here
  })
})

在这个文件中,我们_describing_了List.vue组件,并且我们创建了一个空的测试,他将要检查这个组件的列表展示。这是一个基本的 Mocha 测试文件。

我们首先要安装我们的Vue组件。复制下面代码放在测试文件的"our test goes here"下面:

// build component
const Constructor = Vue.extend(List);
const ListComponent = new Constructor().$mount();

我们继承了Vue组件并且安装这个组件。安装组件很重要,只有这样我们才能将通过模板来渲染HTML。也就是说,HTML已经被创建,并且我们模板中的变量(比如 item)已经被填充内容,这样我们就可以获取HTML了(使用$el)。

我们的组件准备好了,我们可以写第一个断言。在这个例子中,我们使用Chai 断言库提供的 "expect" 模式,还有 "should" 和 "assert"模式。将下面的代码放到,启动组件的后面。

// assert that component text contains items from the list
expect(ListComponent.$el.textContent).to.contain("play games");

之前提到过,我们可以使用ListComponent.$el来获取组件的HTML,如果想去获取HTML内的内容(比如 文本),我们可以使用ListComponent.$el.textContent。这个断言用来检查HTML列表中的文本是否和组件的data里的数据列表吻合。

为了检查所有的事情都符合我们的预期,我们可以运行测试!通过 vue-cli 创建的项目,我们可以简单的使用npm run unit来运行cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run

npm run unit

如果测试都通过了,将会有一个绿色的列表来显示测试报告,让你了解测试都覆盖了哪些代码。

模拟用户输入

虽然前面的功能赞赞哒,但没有多少应用只是用来展示数据。下一步我们要做到是添加新的项目到to-do list中。看这里,我们创建了一个input框来输入内容,然后创建一个button用来提交内容。下面是更新后的 List.vue:



使用v-model,输入框里面的内容将和newItem进行双向绑定。当按钮被点击后,执行addItemToList,将newItem添加到to-do list数组里面,并且清空newItem里面的内容,新的项目将会被添加到列表中。

可以为新功能写测试文件了,创建List.spec.js,并且添加以下测试代码。

it("adds a new item to list on click", () => {
    // our test goes here
})

第一步,我们需要创建我们的组件,并且模拟一个用户在输入框的输入行为。因为 VueJs 将输入框和 newItem 变量进行了绑定,我们可以给newItem设置内容。

// build component
const Constructor = Vue.extend(List);
const ListComponent = new Constructor().$mount();

// set value of new item
ListComponent.newItem = "brush my teeth";

下一步,我们需要点击按钮。我们需要在HTML中找到按钮,在$el中即可找到。这是,我们可以使用querySelector,像选择真是元素一样选择这个按钮。也可以使用class(.buttonClass)、ID(#buttonID)或者标签名(button)来选择。

// find button
const button = ListComponent.$el.querySelector("button");

为了模拟点击,我们需要给按钮一个新的事件对象。在测试环境中,List组件不会监听任何事件,因此我们需要手动运行watcher

// simulate click event
const clickEvent = new window.Event("click");
button.dispatchEvent(clickEvent);
ListComponent._watcher.run();

最后,我们需要检查我们添加的新项目是否显示在HTML中,这个在前面已经介绍过。我们也需要检查newItem是否被存储在了数组里面。

//assert list contains new item
expect(ListComponent.$el.textContent).to.contain("brush my teeth");
expect(ListComponent.listItems).to.contain("brush my teeth");

下面是整个测试文件的内容:

import List from "@/components/List";
import Vue from "vue";

describe("List.vue", () => {
  it("displays items from the list", () => {
    const Constructor = Vue.extend(List);
    const ListComponent = new Constructor().$mount();
    expect(ListComponent.$el.textContent).to.contain("play games");
  })

  it("adds a new item to list on click", () => {
    // build component
    const Constructor = Vue.extend(List);
    const ListComponent = new Constructor().$mount();

    // set input value
    ListComponent.newItem = "brush my teeth";

    // simulate click event
    const button = ListComponent.$el.querySelector("button");
    const clickEvent = new window.Event("click");
    button.dispatchEvent(clickEvent);
    ListComponent._watcher.run();

    // assert list contains new item
    expect(ListComponent.$el.textContent).to.contain("brush my teeth");
    expect(ListComponent.listItems).to.contain("brush my teeth");
  })
})

现在跑一次这个测试,应该全是绿色的。

希望你读这些代码的时候思路能够清晰,不过它对于刚刚开始接触VueJs单元测试的人来说可读性并不是很高。有一个VueJS实用程序库,它将一些复杂的代码进行了封装。如果想使用它,可以在项目的根目录下输入以下命令安装。

npm install avoriaz

下面这个测试实际上和上面测试相同,只不过写法上有些不同。我们使用了mount()法来安装Vue组件,使用find()获取按钮,使用dispatch()来触发点击。

import { mount } from "avoriaz";
import List from "@/components/List";
import Vue from "vue";

describe("List.vue", () => {
  // previous tests ..

  it("adds new item to list on click with avoriaz", () => {
       // build component
    const ListComponent = mount(List);

    // set input value
    ListComponent.setData({
      newItem: "brush my teeth",
    });

    // simulate click event
    const button = ListComponent.find("button")[0];
    button.dispatch("click");

    // assert list contains new item
    expect(ListComponent.text()).to.contain("brush my teeth");
    expect(ListComponent.data().listItems).to.contain("brush my teeth");
  })
})
总结

在日常工作以及JavaScript开发中,尤其是VueJS项目,测试是非常重要的。因为刚开始接触测试的时候,我遇到了一些问题,所以总结出一篇文章供大家参考。希望这篇文章能够帮到所有像我一样的人。

这个git库是这次教程所有的代码。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84100.html

相关文章

  • 2017-07-19 前端日报

    摘要:前端日报精选开发常见问题集锦前端码农的自我修养虚拟内部是如何工作的译知乎专栏并不慢,只是你使用姿势不对一份优化指南掘金老司机带你秒懂内存管理第一部中文免费公开课前端面试的大关键点,你到了吗知乎专栏高效开发与设计姐的图片二三 2017-07-19 前端日报 精选 VueJS 开发常见问题集锦 - 前端码农的自我修养 - SegmentFault虚拟 DOM 内部是如何工作的?[译]Hig...

    iflove 评论0 收藏0
  • 何为你的 Vue 项目添加配置 Stylelint

    摘要:如何为你的项目添加配置如何为你的项目添加配置现在已经是年了,网上许多教程和分享帖都已经过期,照着他们的步骤来会踩一些坑,如已经不再维护,以及之后文件只剩下部分等。如有疑问或授权协商请与我联系。如何为你的 Vue 项目添加配置 Stylelint 现在已经是 9102 年了,网上许多教程和分享帖都已经过期,照着他们的步骤来会踩一些坑,如 stylelint-processor-html 已经不...

    番茄西红柿 评论0 收藏0
  • 2017-07-18 前端日报

    摘要:前端日报精选常用实例的实现与封装实现一个构建基于的可扩展应用规范翻译从到中文开源中国两级缓存实践掘金中基于的自动实体类构建与接口文档生成某熊的全栈之路继承总结教程中的五种组件形式掘金再说的问题前端开发前端每周清单第期正式 2017-07-18 前端日报 精选 javascript常用实例的实现与封装实现一个 SwiperRekit 2.0 构建基于React+Redux+React-r...

    lauren_liuling 评论0 收藏0
  • Vuejs自己的构建工具

    摘要:然而,这些模板并不限制你自己对于使用的架构组织和选择类库。目前可用的模板包括全功能的,包括热加载,静态检测,单元测试一个简易的,以便于快速开始。 最近, 尤大在和人对喷的时候,悄然放出了一个大招,于是为了追赶他的步伐,赶紧试验了下,并且把原文给大家翻译下。 原文地址:Announcing vue-cli 译文源地址: Vuejs自己的构建工具 先上原文翻译: 最近有很多大量关于Reac...

    leoperfect 评论0 收藏0
  • 正在失业中的《课多周刊》(第3期)

    摘要:正在失业中的课多周刊第期我们的微信公众号,更多精彩内容皆在微信公众号,欢迎关注。若有帮助,请把课多周刊推荐给你的朋友,你的支持是我们最大的动力。是一种祸害译本文浅谈了在中关于的不好之处。浅谈超时一运维的排查方式。 正在失业中的《课多周刊》(第3期) 我们的微信公众号:fed-talk,更多精彩内容皆在微信公众号,欢迎关注。 若有帮助,请把 课多周刊 推荐给你的朋友,你的支持是我们最大的...

    robin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<