Viết test cho VueJS

Việc đảm bảo chất lượng dự án luôn là điều cần thiết, có nhiều cách để thể hiện chất lượng dự án, viết test cho dự án thể hiện khá rõ ràng chất lượng cuả nó. Mình sẽ giới thiệu các bạn viết test cho dự án viết bằng VueJS.

Các công cụ cần thiết

Trước tiên là làm việc với Vue nên các plugin cho vue sẽ là vue vue-template-compiler vue-loader Hiện tại để test cho Vue thì có thể kể đến 3 thư viện là Jest, Mocha và Karma. Ở trong bài này mình sẽ làm việc với Mocha, các thư viện khác khá tương tự, và các plugin sẽ cần là vue-test-utils mocha webpack mocha-webpack.

Vue Test Utils yêu cầu môi trường trình duyệt để chạy. Chúng ta có thể mô phỏng nó bằng cách sử dụng jsdom-global, các plugin là jsdom jsdom-global.

Và sử dụng 1 thư viện để kiểm tra, mình sẽ chọn expect, đây là thư viện rất nổi tiếng và được sử dụng rất rộng rãi trong việc testing cho Javascript. Tổng kết lại các thư việc cần cài đặt sẽ như sau:

"dependencies": {
    "expect": "^23.4.0",
    "jsdom": "^11.11.0",
    "jsdom-global": "^3.0.2",
    "mocha": "^5.2.0",
    "mocha-webpack": "^1.1.0",
    "vue": "^2.5.16",
    "vue-loader": "^15.2.4",
    "vue-template-compiler": "^2.5.16",
    "vue-test-utils": "^1.0.0-beta.11",
    "webpack": "^4.16.0"
}

Cấu hình

Cấu hình một chút để có thể chạy test, và file test/setup.js sẽ cấu hình một chút như sau:

require('jsdom-global')()

Và có sử dụng webpack nên cần cấu hình, file webpack.config.js như sau:

const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: 'vue-loader',
            },
        ],
    },
    plugins: [
        new VueLoaderPlugin(),
    ],
};

Và lệnh để chạy test, mình sẽ có 2 lệnh sau, 1 để chạy test và 1 để chạy test và tự động theo dõi sự thay đổi. Trong file package.json bạn thêm 2 lệnh sau tại scripts

   "test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js",
   "test-watch": "mocha-webpack --webpack-config webpack.config.js --watch --require test/setup.js test/**/*.spec.js"

Các API của package vue-test-utils

  • mount(): Khi sử dụng api trên thì ta sẽ được wrapper của component đã được mounted và rendered.
  • shallowMount(): Giống như mount nhưng giản lược các component con bằng các stub
  • render(): Khi sử dụng thì sẽ được wrapper của component được rendered thành một cheerio wrapper . Cherrio là một thư viện giúp bạn thao các với wrapper tương tự Jquery để duyệt cấu trúc DOM của wrapper. Và render sử dụng package @vue/server-test-utils
  • renderToString(): Giống như render ở trên, nhưng thay vì tạo ra một cherrio wrapper thì sẽ tạo thành HTML, bạn sẽ thao tác với DOM như khi dùng JS thuần.

Thao tác với Wrapper

Các api trên giúp bạn tạo thành một wrapper, bạn lựa chọn phương thức phù hợp, và các thao tác với wrapper. Các properties của wrapper:

  • vm: Đây là một instance của Vue, bạn có thể truy xuất các thuộc tính và phương thức của Vue thông qua wrapper.vm.
  • element: sẽ trả về root DOM của wrapper.
  • options: sẽ trả về các option khi bạn thiết lập wrapper.

Các phương thức trên Wrapper:

  • attributes(): trả về một object chứa các attributes của DOM, bạn sẽ truy xuất được atribute qua trên của nó.
  • classes(): trả về một mảng các class được sử dụng.
  • contains(selector): kiểm tra xem thành phần selector có xuất hiện trong wrapper hay không.
  • emitted(): sẽ trả về object chứa các event được emitted bởi Instace của Vue là Wrapper vm ở trên
  • exists(): đơn giản là kiểm trả xem có tồn tại Wrapper hay không.
  • find(selector): trả về phần tử đầu tiên phù hợp với selector, sau đó bạn có thể sử dụng các method ở trên.
  • findAll(selector): thay vì trả về phần tử đầu tiên, sẽ trả về mảng các phần tử phủ hợp được tìm thấy.
  • html(): trả về HTML nằm trong wrapper.
  • isVueInstance(): kiểm tra xem có phải là một instance của Vue hay không.
  • props(): trả về một object các props được truyền vào cho compnent.
  • setData(data): phương thức này sẽ gộp với data hiện có của wrapper, và thay thế hoặc tạo mới data được truyền vào.
  • setMethods(methods): thiết lập methods và sẽ update lại component.
  • setProps(props): tương tự như setData nhưng là cho prop.
  • text(): trả về phần nội dung nằm trong Wrapper.
  • trigger(eventType [, options]): trigger một event trên DOM, và options kèm theo sẽ được thêm vào methods khi event được xảy ra.

Kiểm tra kết qủa trên Wrapper

Sau khi sử dụng các methods phù hợp, ta sẽ nhận được kết quả, và sẽ dùng thư viện expect để kiểm tra kết quả nhận được. Bạn có thể đọc chi tiết thư việc expect ở link trên. Ta hãy thử một ví dụ đơn giản.

// src/TestComponent.vue
<template>
    <div>Test component</div>
</template>
<script>
    export default {
        name: 'TestComponent'
    }
</script>

Giờ ta sẽ test thử component ở trên

// test/test-component.spec.js
import { mount } from 'vue-test-utils' // Bạn có thể sử dụng các api khác như shallowMount, render, renderToString
import expect from 'expect'
import TestComponent from '../src/TestComponent.vue'

describe('Testing for TestComponent', () => {
    it('test contain text', () => {
        const wrapper = mount(TestComponent)
        expect(wrapper.text()).toContain('Test component')
    })
})

Và chạy npm run test hoặc npm run test-watch để nhận thông báo kết quả từ việc testing.

Như thế là mình đã viết sơ bộ về việc testing cho dự án sử dụng VueJS, bài viết chỉ ở mức liệt kê và chưa có ví dụ cụ thể, các bạn có thể đọc cụ thể hơn tại Doc testing with vue-test-utils