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

本文介绍如何为Vue.js应用创建单元测试,包括环境搭建、基本测试案例编写及模拟用户输入等高级测试技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

搭建环境

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

 
  1. npm install -g vue-cli

  2. vue init webpack project-name

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

 
  1. cd project-name

  2. 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一起使用的断言库。

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

我的第一个测试

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

 
  1. <template>

  2. <div>

  3. <h1>My To Do List</h1>

  4. </br>

  5. <!--displays list -->

  6. <ul>

  7. <li v-for="item in listItems">{{ item }}</li>

  8. </ul>

  9. </div>

  10. </template>

  11.  
  12. <script>

  13. export default {

  14. name: 'list',

  15. data () {

  16. return {

  17. listItems: ['buy food', 'play games', 'sleep'],

  18. }

  19. }

  20. }

  21. </script>

在组件中,列表项存储在组件数据中的数组(listItems)中。然后可以在模板中访问该数据,并在foreach循环中循环(v-for),并显示在页面上。

为了使我们的列表看起来更有趣,我们可以创建一个新的路径来显示我们的组件。进入src/router/index.js并添加路由,你的代码应该是这样的:

 
  1. import Vue from 'vue'

  2. import Router from 'vue-router'

  3. import Hello from '@/components/Hello'

  4. import List from '@/components/List'

  5.  
  6. Vue.use(Router)

  7.  
  8. export default new Router({

  9. routes: [

  10. {

  11. path: '/',

  12. name: 'Hello',

  13. component: Hello

  14. },

  15. {

  16. path: '/to-do',

  17. name: 'ToDo',

  18. component: List

  19. },

  20. ]

  21. })

现在,如果您导航到localhost:8080/#/to-do,您将在浏览器中看到您的列表效果!

首先我们要测试数据是否正确显示。在 test/unit/specs 下创建一个新的文件List.spec.js并放上如下代码:

 
  1. import List from '@/components/List';

  2. import Vue from 'vue';

  3.  
  4. describe('List.vue', () => {

  5.  
  6. it('displays items from the list', () => {

  7. // our test goes here

  8. })

  9. })

在这个文件中,我们描述List.vue组件,我们有一个单独的空测试,它将检查它(组件)是否从列表中显示项目。这是Mocha测试的基本文件结构。

在我们的测试中,我们首先需要设置Vue组件。复制下面的代码,并将其放在注释“our test goes here”的位置:

 
  1. // build component

  2. const Constructor = Vue.extend(List);

  3. const ListComponent = new Constructor().$mount();

我们扩展Vue然后安装我们的组件。安装组件很重要,因为这是在我们的模板中呈现HTML。这实际上意味着HTML被构建,并且我们的模板中的变量(例如{{item}})被填满数据,使得我们可以访问HTML(通过$el)。

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

 
  1. // assert that component text contains items from the list

  2. 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的更新版本:

 
  1. <template>

  2. <div>

  3. <h1>My To Do List</h1>

  4. </br>

  5. <input v-model="newItem" >

  6. <button @click="addItemToList">Add</button>

  7. <!-- displays list -->

  8. <ul>

  9. <li v-for="item in listItems">{{ item }}</li>

  10. </ul>

  11. </div>

  12. </template>

  13.  
  14. <script>

  15. export default {

  16. name: 'test',

  17. data () {

  18. return {

  19. listItems: ['buy food', 'play games', 'sleep'],

  20. newItem: ''

  21. }

  22. },

  23. methods: {

  24. addItemToList() {

  25. this.listItems.push(this.newItem);

  26. this.newItem = '';

  27. }

  28. }

  29. }

  30. </script>

使用v-model,输入框的值绑定到存储在组件数据中的newItem变量。当单击按钮时,将执行addItemToList函数,将newItem添加到列表数组中,并清除newItem,以便可以将更多的内容添加到列表中。

要开始测试此功能,请在List.spec.js中创建一个新的空测试,并添加测试代码:

 
  1. it('adds a new item to list on click', () => {

  2. // our test goes here

  3. })

首先我们要构建我们的组件,并模拟一个用户在输入框中输入的内容。由于VueJS将输入框的值绑定到newItem变量,所以我们可以简单地将我们的值设置为newItem

 
  1. // build component

  2. const Constructor = Vue.extend(List);

  3. const ListComponent = new Constructor().$mount();

  4.  
  5. // set value of new item

  6. ListComponent.newItem = 'brush my teeth';

接下来我们需要点击按钮。我们必须在HTML中找到这个按钮,它可以使用$el。只有这一次,我们才可以使用querySelector来查找实际的元素。可以使用它的类(.buttonClass),其id(#buttonId)或元素的名称(button)来找到一个元素。

 
  1. // find button

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

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

 
  1. // simulate click event

  2. const clickEvent = new window.Event('click');

  3. button.dispatchEvent(clickEvent);

  4. ListComponent._watcher.run();

最后,我们需要检查newItem是否显示,我们已经知道如何从第一个测试中完成!我们可能还想检查newItem是否存储在列表数组中。

 
  1. //assert list contains new item

  2. expect(ListComponent.$el.textContent).to.contain('brush my teeth');

  3. expect(ListComponent.listItems).to.contain('brush my teeth');

以下是完整的测试文件:

 
  1. import List from '@/components/List';

  2. import Vue from 'vue';

  3.  
  4. describe('List.vue', () => {

  5. it('displays items from the list', () => {

  6. const Constructor = Vue.extend(List);

  7. const ListComponent = new Constructor().$mount();

  8. expect(ListComponent.$el.textContent).to.contain('play games');

  9. })

  10.  
  11. it('adds a new item to list on click', () => {

  12. // build component

  13. const Constructor = Vue.extend(List);

  14. const ListComponent = new Constructor().$mount();

  15.  
  16. // set input value

  17. ListComponent.newItem = 'brush my teeth';

  18.  
  19. // simulate click event

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

  21. const clickEvent = new window.Event('click');

  22. button.dispatchEvent(clickEvent);

  23. ListComponent._watcher.run();

  24.  
  25. // assert list contains new item

  26. expect(ListComponent.$el.textContent).to.contain('brush my teeth');

  27. expect(ListComponent.listItems).to.contain('brush my teeth');

  28. })

  29. })

现在我们可以再次运行我们的测试,应该会显示绿色!

希望这段代码对你来说能够很清楚,但是它不是特别容易理解,特别是对于第一次进行VueJS测试的人来说。有一个VueJS实用程序库,其中包含了一些更复杂的外观代码。要使用它,我们可以转到我们的项目根目录并运行以下命令:

npm install avoriaz

现在我们可以隐藏mount()之后的Vue组件的设置,并且为了单击按钮,我们需要的是两行代码:find()该按钮和dispatch() )点击事件。

 
  1. import { mount } from 'avoriaz';

  2. import List from '@/components/List';

  3. import Vue from 'vue';

  4.  
  5. describe('List.vue', () => {

  6. // previous tests ..

  7.  
  8. it('adds new item to list on click with avoriaz', () => {

  9. // build component

  10. const ListComponent = mount(List);

  11.  
  12. // set input value

  13. ListComponent.setData({

  14. newItem: 'brush my teeth',

  15. });

  16.  
  17. // simulate click event

  18. const button = ListComponent.find('button')[0];

  19. button.dispatch('click');

  20.  
  21. // assert list contains new item

  22. expect(ListComponent.text()).to.contain('brush my teeth');

  23. expect(ListComponent.data().listItems).to.contain('brush my teeth');

  24. })

  25. })

总结

我个人认为写作测试对于我的正常工作流程至关重要,但是使用JavaScript,特别是VueJS,我开始碰到一些麻烦。希望本教程将帮助任何与我一样遇到麻烦的人!

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

原文地址:http://f2ex.cn/how-to-write-a-unit-test-for-vuejs/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值