测试驱动开发Vuejs(一)

十月初 Vuejs官方团队发布了测试套件 vue-test-utils github 地址 / 官方网站 本文主要是参考官方的指南 和一个国外的视频教程

创建项目

    mkdir vuetest
    cd vuetest
    npm init -Y  // 创建 package.json
    npm install --save-dev vue-test-utils webpack mocha mocha-webpack // 本教程主要使用的工具

项目的结构

├── /src
│  └── components
│     └── Counter.js
│  
├── /test
│  └── counter.spec.js
│
└── package.json

改写 package.json 中的 test script

// package.json
{
  "scripts": {
    "test": "mocha-webpack --webpack-config webpack.config.js  test/*.spec.js"
  }
}

--webpack-config 要指定webpack的配置文件,为了集中精力学习测试而不是配置一个webpack。 这里我们在项目根目录创建一个空的文件 webpack.config.js

第一个测试

我们期望 Counter 在初始化时有一个 data count 并且值为0

先安装一个预言库 expect

    npm install --save-dev expect
//- counter.spec.js
import { mount } from 'vue-test-utils';
import Counter from '../src/components/Counter';
import expect from 'expect';

describe( 'Counter', () => {

    it ('defaults to a count to 0', () => {
        let wrapper = mount(Counter)
        expect(wrapper.vm.count).toBe(0)
    });
    
});

//- Counter.js
export default {
    data() {
        return {
            count: 0
        }
    }
}
    npm test
    // ...
    //   ERROR in ./node_modules/vue-test-utils/dist/vue-test-utils.js
    //   Module not found: Error: Can't resolve 'vue-template-compiler' in '/Users/lu/WebstormProjects/testvue/node_modules/vue-test-utils/dist'
    // ...

第一个测试失败了,是因为没有安装jsdom 和错误信息中提到的 vue-template-compiler

    npm install --save-dev jsdom jsdom-global vue-template-compiler

并且按照官方指南, 在测试运行前指定环境为浏览器。 新增test/setup.js

// test/setup.js
    require('jsdom-global')()

调整 test script

// package.json
{
  "scripts": {
     "test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/*.spec.js"
  }
}

现在第一个测试可以通过了。

测试 dom 相关

从上一个例子中可以看到 ,vue-test-utils 是可以渲染dom的。现在增加一个测试

// counter.spec.js
import { mount } from 'vue-test-utils';
import Counter from '../src/components/Counter';
import expect from 'expect';

describe( 'Counter', () => {
    let wrapper = mount(Counter)

    it ('defaults to a count to 0', () => {
        expect(wrapper.vm.count).toBe(0)
    });

    it ('presents the current count', () => {
        expect(wrapper.find('.count').html()).toContain(0)
    })

});
// Counter.js
export default {
    template: `
        <div><span class="count">8</span></div> 
    `,
    data() {
        return {
            count: 0
        }
    }
}

第三个测试

从 vue-test-utils 网站上可以看到 ,它是可以 trigger dom事件的,如click 等。现在增加第三个测试

// counter.spec.js
import { mount } from 'vue-test-utils';
import Counter from '../src/components/Counter';
import expect from 'expect';

describe( 'Counter', () => {
    let wrapper = mount(Counter)

    it ('defaults to a count to 0', () => {
        expect(wrapper.vm.count).toBe(0)
    });

    it ('increments the count when the button is click', () => {
        expect(wrapper.vm.count).toBe(0);
        wrapper.find('button').trigger('click');
        expect(wrapper.vm.count).toBe(1);
    })

    it ('presents the current count', () => {
        expect(wrapper.find('.count').html()).toContain(0)
    })

});
// Counter.js
export default {
    template: `
        <div><button @click="count++">+</button><span class="count">8</span></div> 
    `,
    data() {
        return {
            count: 0
        }
    }
}

测试结果第二个通过了 但是第三个失败了,因为这时count 已经是1了。我们可以手动修改 第三个 expect

  expect(wrapper.find('.count').html()).toContain(1)

或者在每个测试前重置wrapper

// counter.spec.js
import { mount } from 'vue-test-utils';
import Counter from '../src/components/Counter';
import expect from 'expect';

describe( 'Counter', () => {
    let wrapper;
    beforeEach(() => {
        wrapper = mount(Counter)
    })
    it ('defaults to a count to 0', () => {
        expect(wrapper.vm.count).toBe(0)
    });

    it ('increments the count when the button is click', () => {
        expect(wrapper.vm.count).toBe(0);
        wrapper.find('button').trigger('click');
        expect(wrapper.vm.count).toBe(1);
    })

    it ('presents the current count', () => {
        expect(wrapper.find('.count').html()).toContain(0)
    })

});

本文是我在看完视频教程后的一个总结。只要安装好依赖,仔细阅读官方的指南,其实还是蛮简单的。 只是官方指南依赖现有的项目和webpack配置。比如我们这里将Counter.js 改写为Counter.vue。 会出现无法处理 .vue文件的问题。新手会陷入webpack配置中无法自拔。 视频教程的优点是它的第一节课是没有webpack配置的,使用的是js文件。第二节课才讲如何配置webpack和 vue文件。

原教程地址

https://laracasts.com/series/testing-vue/episodes/1

Written on October 18, 2017