vlambda博客
学习文章列表

基于 Vue 测试套件引入 Mocha + Expect 测试 Vue 组件

一、Vue 测试套件

天下乌鸦一般黑,天下的单元测试流程也都差不多。

在 Vue 框架中编写单元测试的基本流程和学院君之前在 Laravel 框架和 Go-Micro 微服务框架中编写单元测试时一模一样,只是使用的测试框架和语法有所区别罢了,Laravel 中我们使用的测试框架是 PHPUnit,Go-Micro 中我们使用的测试框架是 GoConvey,而在 Vue 框架中,我们将使用 Vue 生态的 Vue 测试套件并引入 Mocha 测试框架进行 BDD 风格的单元测试。

你可以参照Vue 官方文档通过 NPM 安装相应的依赖包,不过这里为了方便后端程序员快速入门,我们绕过 Webpack 的繁琐配置,直接基于 Laravel Mix 引入 Vue 测试套件和 Mocha 测试框架。

开始之前,先初始化一个新的 Laravel 项目 component-test,并通过 laravel/ui 扩展包预置 Vue 依赖包和示例组件:

laravel new component-test
cd component-test 
composer require laravel/ui
php artisan ui vue
npm install

二、引入 Mocha 测试框架

component-test 项目根目录下运行如下命令初始化 Vue 测试套件相关的前端依赖:

npm install --save-dev @vue/test-utils mocha mochapack jsdom jsdom-global expect

前三个是 Vue 测试套件和 Mocha 测试框架,jsdom 用于模拟浏览器环境,Expect 则是一个前端测试断言库(类似 PHPUnit 中的 assert)。

编写测试命令

安装完成后,在 package.json 中配置一个 mochapack 测试命令:

"scripts": {
    ...
    "test""cross-env NODE_ENV=development mochapack --webpack-config webpack.config.js --require tests/JavaScript/setup.js tests/JavaScript/**/*.spec.js"
}

自定义 Webpack 配置文件

其中 --webpack-config 用于指定了该测试使用的 Webpack 配置文件,这里为了方便对其进行自定义,我们在 component-test 根目录下新建了一个 webpack.config.js,并初始化配置代码如下:

let path = require('path');
let { VueLoaderPlugin } = require('vue-loader');

module.exports = {
    mode"development",
    module: {
        rules: [
            {
                test/\.vue$/,
                loader'vue-loader',
                exclude/node_modules/
            },
            {
                test/\.js$/,
                loader'babel-loader',
                exclude/node_modules/
            },
            {
                test/\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin()
    ]
}

初始化测试资源

回到 mochapack 测试命令,--require 用于指定每次测试前会运行 tests/JavaScript/setup.js 进行一些测试资源初始化操作,类似 PHPUnit 中的 setUp 方法。

我们在 component-test 根目录下的 tests 目录中创建 JavaScript 子目录用于存放测试用例文件,然后在该子目录下新建 setup.js,在这里我们先引入 jsdom-global 并设置全局的断言实例:

require('jsdom-global')();
global.expect = require('expect');

mochapack 测试命令最后的 tests/JavaScript/**/*.spec.js 表示所有测试用例文件都存放在 tests/JavaScript 目录下,这些测试文件都以 .spec.js 作为文件名后缀,并且可以位于 tests/JavaScript 目录下任意层级的子目录中,当运行 npm run test 进行测试时会在这些目录中寻找测试用例执行。

运行测试命令

接下来,我们运行 npm run test 执行一次测试,由于还没有编写任何测试用例,所以测试通过:

基于 Vue 测试套件引入 Mocha + Expect 测试 Vue 组件

三、测试 Vue 单文件组件

最后,我们编写一个测试用例来测试 laravel/ui 扩展包提供的示例 Vue 组件 ExampleComponent.vue

编写测试用例

tests/JavaScript 目录下新建一个 example.spec.js 测试文件,编写一段简单的 BDD 风格测试代码如下:

import { mount} from "@vue/test-utils";
import { ExampleComponent } from '../../resources/js/components/ExampleComponent.vue';

describe('ExampleComponent.vue', () => {
    it('should display specify card title and body'function ({
        let wrapper = mount(ExampleComponent);  // 挂载 Vue 组件

        // 编写断言
        expect(wrapper.find('.card-header').html()).toContain('Example Component');
        expect(wrapper.find('.card-body').html()).toContain('I\'m an example component.');
    });
});

在这个测试文件中,通过 it 定义了针对 ExampleComponent.vue 单文件组件的一个测试用例,我们需要引入 @vue/test-utils 来挂载 Vue 实例,然后基于 setup.js 中声明的全局 expect 实例编写断言代码。这里我们简单判断该组件会包含指定文本的标题和内容。

关于 Mocha 测试框架和 expect 断言的语法细节,可以参考 Mocha 和 expect 官方文档,学院君这里只会演示如何组合这些工具和类库编写测试用例。

执行测试

运行测试命令 npm run test 对上述测试用例进行测试,绿色代表测试通过:


如果我们在测试用例中新增一个断言:

expect(wrapper.find('.card-body').html()).toContain('学院君');

则运行 npm run test 会失败,红色表示测试不通过:

我们可以按照错误提示去修改组件代码让测试通过。

当然,这只是一个最基本的测试用例,还不是标准的 BDD 风格测试代码(Given-When-Then),下篇教程,学院君将给大家演示如何遵循 BDD 风格基于 TDD 模式从头开始开发一个 Vue 单文件组件。

本系列教程首发在Laravel学院(laravelacademy.org),你可以点击页面左下角阅读原文链接查看最新更新的教程。