教你如何编写Vue.js的单元测试的方法


Posted in Javascript onOctober 17, 2018

Vue.js是一个JavaScript框架,可用于构建Web应用程序的前端框架。特别是在创建复杂功能时,对于每个项目,有必要在我们的应用程序中查看所有内容,并检查它是否符合预期。然而,对于大型项目,每次新的更新后,检查每个功能将变得很麻烦。因此,我们可以创建可以一直运行的自动化测试,并保证我们的代码可以正常运行。在本文中,我们将为VueJS创建一些简单的单元测试。

要进行测试,我们将先制作一个基本的待办事项列表组件。我们将测试该列表是否正确显示,并且用户可以将新项目添加到待办事项列表中。希望在本教程结束之前,您可以编写测试,检查您的组件输出给用户,以及通过与HTML进行交互来模拟用户操作(例如通过单击按钮)。

本文中的所有代码可以在 Github 下载。

搭建环境

搭建JavaScript项目可能是一个复杂的过程。有那么多库需要选择,所有这些库的目的都略有不同。幸运的是,对于VueJS,我们有vue-cli,它为我们设定了一切!您需要首先安装npm,然后可以运行以下命令:

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

在这个阶段,你会被提示几个问题。大多数都可以直接继续,您可以选择默认选项,唯一的要求是您回答YES以包括vue-router和YES来设置Karma和Mocha的单元测试。然后安装依赖项:

cd project-name
npm install

这个最终命令将启动您的浏览器并打开localhost运行您的应用程序:

npm run dev

下面是对vue-cli为我们设置的一些关键依赖关系(非常重要)的简要概述,包括为我自己的项目安装的版本。

依赖

Webpack (v2.3) 是一个捆绑器,它结合了各种JavaScript,CSS,HTML(和其他)文件,使他们可以随时由客户端处理。
Babel (v6.22) 是ECMAScript 6到ECMAScript 5的编译器。这些是不同的JavaScript标准,目前的浏览器不能解析所有的ECMAScript 6,因此需要进行转换。

测试依赖关系

Karma (v1.4) 是一个测试运行器,它运行一个Web服务器,其中包含项目的应用程序代码,并对其执行测试。

Mocha (v3.2) 是JavaScript的测试框架。
Chai (v3.5) 是可以与Mocha一起使用的断言库。

在您的项目中,您应该能找到以下文件夹:build,config,node_modules,src,static和test。对本文来说,重要的是src,它将保存我们的应用程序代码并进行test。

我的第一个测试

一个好的开始需要去做一些基本工作。我们将从创建简单列表组件开始。在src/components文件夹中创建一个名为List.vue的新文件,并将以下代码放在里面:

<template>
 <div>
  <h1>My To Do List</h1>
  </br>
  <!--displays list -->
  <ul>
   <li v-for="item in listItems">{{ item }}</li>
  </ul>
 </div>
</template>
 
<script>
export default {
 name: 'list',
 data () {
  return {
   listItems: ['buy food', 'play games', 'sleep'],
  }
 }
}
</script>

在组件中,列表项存储在组件数据中的数组(listItems)中。然后可以在模板中访问该数据,并在foreach循环中循环(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
 })
})

在这个文件中,我们描述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)。

随着我们的组件准备好,我们可以写第一个断言。在这个例子中,我们使用了'expect'风格,由Chai断言库提供,以及'should'和'assert'。 安装组件后放置以下代码:

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

如上所述,我们可以使用ListComponent.$el获取组件的HTML,并且使用ListComponent.$el.textContent只访问内部HTML(即文本)。断言是检查文本是否包含在组件数据中设置的列表项之一。

为了检查一切都能正常工作,我们可以运行测试!使用vue-cli项目,我们可以简单地输入npm run unit,这是一个别名 cross-env BABEL_ENV = test karma start test/unit/karma.conf.js --single-run。

npm run unit

如果所有的测试都已经通过,它将显示绿色,并显示成功测试和代码覆盖率报告的列表,让您知道在测试期间执行的应用程序代码的百分比。

模拟用户输入

这是一个很好的开始,但是很少有应用程序只会显示数据。我们要添加的下一个功能是让用户能够在其列表中添加新项目。为此,我们需要一个输入框,用户可以在其中键入新项目,并在按钮上添加项目到列表中。这是List.vue的更新版本:

<template>
 <div>
  <h1>My To Do List</h1>
  </br>
  <input v-model="newItem" >
  <button @click="addItemToList">Add</button>
  <!-- displays list --> 
  <ul>
   <li v-for="item in listItems">{{ item }}</li>
  </ul>
 </div>
</template>
 
<script>
export default {
 name: 'test',
 data () {
  return {
   listItems: ['buy food', 'play games', 'sleep'],
   newItem: ''
  }
 },
 methods: {
   addItemToList() {
    this.listItems.push(this.newItem);
    this.newItem = '';
   }
 }
}
</script>

使用v-model,输入框的值绑定到存储在组件数据中的newItem变量。当单击按钮时,将执行addItemToList函数,将newItem添加到列表数组中,并清除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来查找实际的元素。可以使用它的类(.buttonClass),其id(#buttonId)或元素的名称(button)来找到一个元素。

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

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

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

最后,我们需要检查newItem是否显示,我们已经知道如何从第一个测试中完成!我们可能还想检查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,我开始碰到一些麻烦。希望本教程将帮助任何与我一样遇到麻烦的人!

本文中的所有代码可以在 Github 下载。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中的值是按值传递还是按引用传递问题探讨
Jan 30 Javascript
详解Backbone.js框架中的模型Model与其集合collection
May 05 Javascript
bootstrap警告框使用方法解析
Jan 13 Javascript
详解Vue中状态管理Vuex
May 11 Javascript
react-native-fs实现文件下载、文本存储的示例代码
Sep 22 Javascript
vue cli webpack中使用sass的方法
Feb 24 Javascript
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
JS实现获取进今年第几天是周几的方法分析
Jun 27 Javascript
Vue中使用 setTimeout() setInterval()函数的问题
Sep 13 Javascript
Vue的H5页面唤起支付宝支付功能
Apr 18 Javascript
mock.js模拟数据实现前后端分离
Jul 24 Javascript
js前端如何写一个精确的倒计时代码
Oct 25 Javascript
详解vue如何使用rules对表单字段进行校验
Oct 17 #Javascript
Vue绑定内联样式问题
Oct 17 #Javascript
react 应用多入口配置及实践总结
Oct 17 #Javascript
vue+echarts实现动态绘制图表及异步加载数据的方法
Oct 17 #Javascript
手把手教你写一个微信小程序(推荐)
Oct 17 #Javascript
微信小程序开发之tabbar图标和颜色的实现
Oct 17 #Javascript
解决百度Echarts图表坐标轴越界的方法
Oct 17 #Javascript
You might like
php 显示指定路径下的图片
2009/10/29 PHP
jQuery的强大选择器小结
2009/12/27 Javascript
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
2012/12/13 Javascript
通过JQuery实现win8一样酷炫的动态磁贴效果(示例代码)
2013/07/13 Javascript
javascript中数组的sort()方法的使用介绍
2013/12/18 Javascript
用JS在浏览器中创建下载文件
2014/03/05 Javascript
jQery使网页在显示器上居中显示适用于任何分辨率
2014/06/09 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
javascript实现简单的html5视频播放器
2015/05/06 Javascript
基于jquery实现可定制的web在线富文本编辑器附源码下载
2015/11/17 Javascript
jquery.Callbacks的实现详解
2016/11/30 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
jQuery开源组件BootstrapValidator使用详解
2017/06/29 jQuery
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
快速解决处理后台返回json数据格式的问题
2018/08/07 Javascript
JS原生瀑布流效果实现
2019/04/26 Javascript
详解vue 组件
2020/06/11 Javascript
windows下python模拟鼠标点击和键盘输示例
2014/02/28 Python
python通过wxPython打开一个音频文件并播放的方法
2015/03/25 Python
python在ubuntu中的几种安装方法(小结)
2017/12/08 Python
python3.x实现发送邮件功能
2018/05/22 Python
python实现树的深度优先遍历与广度优先遍历详解
2019/10/26 Python
Tensorflow累加的实现案例
2020/02/05 Python
python线程里哪种模块比较适合
2020/08/02 Python
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
汽车驾驶求职信
2013/10/25 职场文书
建筑工程技术应届生求职信
2013/11/17 职场文书
《奇妙的国际互联网》 教学反思
2014/02/25 职场文书
团日活动总结格式
2015/05/11 职场文书
因身体原因离职的辞职信范文
2015/05/12 职场文书
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
2021/05/31 Python
mysql外连接与内连接查询的不同之处
2021/06/03 MySQL
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL
MySQL 执行数据库更新update操作的时候数据库卡死了
2022/05/02 MySQL