教你如何编写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 相关文章推荐
js获取当前select 元素值的代码
Apr 19 Javascript
node.js中的fs.symlinkSync方法使用说明
Dec 15 Javascript
详谈LABJS按需动态加载js文件
May 07 Javascript
js确认框confirm()用法实例详解
Jan 07 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
Feb 26 Javascript
浅谈JavaScript 浏览器对象
Jun 03 Javascript
jQuery编写设置和获取颜色的插件
Jan 09 Javascript
JavaScript实现焦点进入文本框内关闭输入法的核心代码
Sep 20 Javascript
VuePress 快速踩坑小结
Feb 14 Javascript
vue路由教程之静态路由
Sep 03 Javascript
JS实现瀑布流效果
Mar 07 Javascript
vue实现lodop打印功能的示例
Nov 11 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 和 MySQL 基础教程(二)
2006/10/09 PHP
php生成的html meta和link标记在body标签里 顶部有个空行
2010/05/18 PHP
php递归获取目录内文件(包含子目录)封装类分享
2013/12/25 PHP
JavaScript 继承的实现
2009/07/09 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
javascript中节点的最近的相关节点访问方法
2013/03/20 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
浅谈如何实现easyui的datebox格式化
2016/06/12 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
微信小程序之MaterialDesign--input组件详解
2017/02/15 Javascript
微信小程序调用PHP后台接口 解析纯html文本
2017/06/13 Javascript
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
Node 升级到最新稳定版的方法分享
2018/05/17 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
用原生JS实现爱奇艺首页导航栏代码实例
2019/09/19 Javascript
小程序分享链接onShareAppMessage的具体用法
2020/05/22 Javascript
详解webpack的文件监听实现(热更新)
2020/09/11 Javascript
[13:16]INFAMOUS vs VGJ T BO3
2018/06/07 DOTA
Python中的高级函数map/reduce使用实例
2015/04/13 Python
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
浅谈Python中range和xrange的区别
2017/12/20 Python
对python pandas读取剪贴板内容的方法详解
2019/01/24 Python
下载官网python并安装的步骤详解
2019/10/12 Python
python集合常见运算案例解析
2019/10/17 Python
Python面向对象封装操作案例详解
2019/12/31 Python
Python能做什么
2020/06/02 Python
RentCars.com巴西:汽车租赁网站
2016/08/22 全球购物
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
陈欧广告词
2014/03/14 职场文书
渠道运营商合作协议书范本
2014/10/06 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
Python中的xlrd模块使用整理
2021/06/15 Python
Vite + React从零开始搭建一个开源组件库
2022/06/25 Javascript