- Published on
การทดสอบระบบโดยใช้ Mocha
- Authors
- Name
- Somprasong Damyos
- @somprasongd
การทดสอบระบบโดยใช้ Mocha
Website: http://mochajs.org/
ติดตั้ง: $ npm i mocha --save-dev
ใช้ -dev
เพราะไม่ต้องการใช้ใน production
การเขียน Test
ควรจะสร้างไฟล์สำหรับทำ Test โดยใช้ชื่อไฟล์ที่ต้องการทดสอบ .test.js
เพราะจะสะดวกตอนรันคำสั่งทดสอบ เช่น
มีไฟล์ชื่อ utils.js
module.exports.add = (a, b) => a + b
module.exports.square = (x) => x * x
ก็สร้างไฟล์ utils.test.js
ขึ้นมา ซึ่งจะสร้าง test case ขึ้นโดยใช้ it('message', () => {});
ซึ่งถ้าผลลัพธ์ไม่ได้อย่างที่ต้องการก็ให้ throw new Error('Message');
ออกไป
const utils = require('./utils')
it('should add two number', () => {
var res = utils.add(33, 11)
if (res !== 44) {
throw new Error(`Expected 44, but got ${res}.`)
}
})
it('should square number', () => {
var res = utils.square(3)
if (res !== 9) {
throw new Error(`Expected 9, but got ${res}.`)
}
})
การทดสอบ
- แก้ไขไฟล์
package.json
ที่ scripts > test เป็นmocha **/utils.test.js
โดย**
หมายถึงให้ดูทุก folder หรือใช้mocha **/*.test.js
ให้เอาทุกไฟล์ที่ลงท้ายด้วย.test.js
"scripts": {
"test": "mocha **/*.test.js"
}
- รันคำสั่ง
$ npm test
- กรณีใช้ร่วมกับ nodemon ใช้
$ nodemon --exec 'npm test'
เพื่อ wacth & auto restart tests หรือจะเอาไปใส่ในpackage.json
เพิ่มในscripts
-->"test-watch": "nodemon --exec \"npm test\""
ไว้ก็ได้
การใช้ร่วมกับ Assertion Library
ตัว assertion library ที่จะใช้ คือ expect
ติดตั้ง: $ npm i expect --save-dev
ใช้ -dev เพราะไม่ต้องการใช้ใน production
การใช้งาน
// using CommonJS modules
var expect = require('expect')
it('should add two number', () => {
var res = utils.add(33, 11)
expect(res).toBe(44)
})
Assertion
expect(object).toBe(xx);
เทียบว่าค่าเท่ากันมั้ย===
expect(object).toNotBe(xx);
เทียบว่าค่าไม่เท่ากันมั้ย!==
expect({name: "Ball"}).toEqual({name: "Ball"});
กรณีเป็น ใช้ toBe ไม่ได้expect({name: "Ball"}).toNotEqual({name: "Ball"});
expect(123).toBeA('number);
ดูว่า type ตรงมั้ยexpect([2, 3, 4]).toInclude(5);
ดูว่ามีค่าอยู่ในนั้นมั้ย ใช้กับ array กับ objectexpect({name: "Ball", age: 31}).toExclude({age: 13});
กรณีใช้ Mocha กับ Async
ที่ callback function ของ it ให้ใส่พารามิเตอร์ชื่อ done และเรียกใช้หลังการตรวจสอบ
// using CommonJS modules
it('should async add two number', (done) => {
utils.asyncAdd(4, 3, (sum) => {
expect(sum).toBe(10).toBeA('number')
done()
})
})
กรณีใช้ Mocha กับ Express
จะใช้โมดูลชื่อ supertest
ติดตั้ง: $ npm i supertest --save-dev
ใช้ -dev เพราะไม่ต้องการใช้ใน production
การใช้งาน
สร้างไฟล์ Web server โดยใช้ express ชื่อ server.js
var express = require('express')
var app = express()
app.get('/', (req, res) => {
res.status(200).send('Hello World!')
})
app.listen(3000)
module.exports.app = app
สร้างไฟล์ mocha test ชื่อ server.test.js
const request = require('supertest')
var app = require('./server.js').app
it('should return hello world response', (done) => {
request(app) // ส่ง express ที่จะทดสอบไป
.get('/') // ระบุ method พร้อม path
.expect(200) // reponse status code
.expect('Hello World!') // response body
.end(done) // เมื่อเสร็จแล้วให้ส่ง callback function done ไป
})
กรณีจะใช้งานร่วมกับโมดูล expect
สร้างไฟล์ Web server โดยใช้ express ชื่อ server.js
var express = require('express')
var app = express()
app.get('/users', (req, res) => {
res.status(200).send([
{
name: 'A',
age: 22,
},
{
name: 'B',
age: 27,
},
{
name: 'C',
age: 28,
},
])
})
app.listen(3000)
module.exports.app = app
สร้างไฟล์ mocha test ชื่อ server.test.js
const request = require('supertest')
const expect = require('expect')
var app = require('./server.js').app
it('should return user object response', (done) => {
request(app)
.get('/users')
.expect(200)
.expect((res) => {
// เปลี่ยนส่วนนี้เป็น callback function รับ response object มา
// ข้างใน function นี้ก็เรียกใช้งานโมดูล expect ได้ตามปกติ
expect(res.body).toInclude({
name: 'A',
age: 22,
})
})
.end(done)
})
จัดการแบ่งกลุ่มการทดสอบโดยใช้ describe()
ปกติถ้ารัน mocha */.test.js โปรแกรมจะปริ้นข้อความต่อกันมาหมด ทำให้แยกยากวันแต่ละบรรทัดเป็นการทดสอบของไฟล์ไหน หรือฟังก์ชันไหน เราจะใช้ decribe('message', () => {});
มาแบ่งกลุ่มกัน ตัวอย่าง
แบบไม่ใช้ describe()
แบบใช้ describe()
const request = require('supertest')
const expect = require('expect')
var app = require('./server.js').app
describe('Server', () => {
describe('GET /', () => {
it('should return hello world response', (done) => {
request(app).get('/').expect(200).expect('Hello World!').end(done)
})
})
describe('GET /error', () => {
// use with expect
it('should return json object response', (done) => {
request(app)
.get('/error')
.expect(404)
.expect((res) => {
expect(res.body).toInclude({
error: 'Page not found!',
})
})
.end(done)
})
})
describe('GET /users', () => {
it('should return user object response', (done) => {
request(app)
.get('/users')
.expect(200)
.expect((res) => {
expect(res.body).toInclude({
name: 'A',
age: 22,
})
})
.end(done)
})
})
})