Tập áp dụng TDD cho dự án sử dụng VueJS
Bài đăng này đã không được cập nhật trong 4 năm
I. Tổng quan
1. TDD là gì?
"Test-Driven Development” có thể được tạm hiểu là mô hình phát triển với trọng tâm hướng về việc kiểm thử. TDD được xây dựng theo hai tiêu chí: Test-First (Kiểm thử trước) và Code-Later (Code sau)
2. Các bước tiến hành TDD
- Viết 1 test cho hàm mới. Đảm bảo rằng test sẽ fail.
- Chuyển qua viết code sơ khai nhất cho hàm đó để test có thể pass.
- Tối ưu hóa đoạn code của hàm vừa viết sao cho đảm bảo test vẫn pass và tối ưu nhất cho việc lập trình kế tiếp
- Lặp lại cho các hàm khác từ bước 1
3. Công cụ cần thiết để thực hiện test JS
Cần 4 thành phần chính như sau
- Test Runners
- Testing Frameworks
- Assertion Libraries
- Testing Plugins
Trong bài viết này mình lựa chọn lần lượt các công cụ: Karma, Mocha, Chai và Sinon
II. Tiến hành
1. Ý tưởng
Mình sẽ thực hiện 1 demo Counter nho nhỏ như hình dưới đây

2. Khởi tạo project
Mình sử dụng vue-cli để setup cho nhanh nhé :slight_smile:
npm install -g vue-cli
vue init webpack tdd-vue
cd tdd-vue
npm install
npm run dev
Mình bắt đầu với file src/components/HelloWorld.vue trước nhé. Làm rỗng file trước đã 
<template>
<div></div>
</template>
<script>
<script>
3. Viết test case đầu tiên
import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'
describe('HelloWorld.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(HelloWorld)
const vm = new Constructor().$mount()
expect(vm.$el.querySelector('h1').textContent)
.to.equal('Welcome to my first TDD :)')
})
})
-
Bạn chạy
npm run unitgiờ chắc chắn sẽ fail. Vì trong file HelloWorld của mình vẫn chưa có gì cả. -
Giờ nhiệm vụ của chúng ta đó là tạo thẻ h1 chứa nội dung
Welcome to my first TDD :)để pass qua test case này
<template>
<div>
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to my first TDD :)',
}
},
}
}
</script>
$ npm run unit
HelloWorld.vue
✓ should render correct contents
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 SUCCESS (0.044 secs / 0.005 secs)
TOTAL: 1 SUCCESS
=============================== Coverage summary ===============================
Statements : 100% ( 1/1 )
Branches : 100% ( 0/0 )
Functions : 100% ( 0/0 )
Lines : 100% ( 1/1 )
- Ok vậy là xong test case đầu tiên.Tuy nhiên khởi tạo
const vmở mỗi test case như này có vẻ hơi "tù". Ta refactor lại và thực hiện viết test kiểm tra biến count như sau
import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'
describe('HelloWorld.vue', () => {
let vm
beforeEach(() => {
const Constructor = Vue.extend(HelloWorld)
vm = new Constructor().$mount()
})
it('should render correct contents', () => {
expect(vm.$el.querySelector('h1').textContent)
.to.equal('Welcome to my first TDD :)')
})
it('should has correct init counter variable', () => {
expect(vm.$data.count).to.equal(0)
})
})
- Code tiếp nào
<template>
<div>
<h1>{{ msg }}</h1>
<h2>{{ count }}</h2>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to my first TDD :)',
count: 0
}
},
}
</script>
$ npm run unit
HelloWorld.vue
✓ should render correct contents
✓ should has correct init counter variable
PhantomJS 2.1.1 (Linux 0.0.0): Executed 2 of 2 SUCCESS (0.045 secs / 0 secs)
TOTAL: 2 SUCCESS
-
Làm tương tự các phần khác. Mình đã comment đầy đủ trong code. Các bạn tham khảo nhé.
-
Chạy lại test lần cuối
$ npm run unit
ButtonComponent.vue
✓ should have to correct button text
✓ should emit event when click button
HelloWorld.vue
✓ should render correct contents
✓ should has correct init counter variable
✓ should has child ButtonComponent
✓ should increment count
✓ should decrement count
✓ should increment count when click increment button
✓ should decrement count when click decrement button
PhantomJS 2.1.1 (Linux 0.0.0): Executed 9 of 9 SUCCESS (0.044 secs / 0.008 secs)
TOTAL: 9 SUCCESS
=============================== Coverage summary ===============================
Statements : 100% ( 6/6 )
Branches : 100% ( 0/0 )
Functions : 100% ( 0/0 )
Lines : 100% ( 6/6 )
Thật tuyệt vời khi nhìn thấy kết quả test xanh lè 100% như này. Chúc các bạn thành công 
Tham khảo:
- https://github.com/tranduykhanh/tdd-vue
- http://blog.co-mit.com/post/9/Tìm+hiểu+mô+hình+TDD+(Test+-+Driven+Development)+và+cách+áp+dụng
- https://blog.octo.com/en/tdd-with-vue-js/
- https://github.com/mochajs/mocha
- https://github.com/karma-runner/karma
- https://github.com/sinonjs/sinon
- https://github.com/chaijs/chai
All rights reserved