ตอนเริ่มเขียน unit test ใหม่ๆ ผมมักได้ยินเสมอว่า เราไม่เขียน unit test UI กัน เพราะ test ได้ยาก พอนึกถึงภาพการเขียน unit test ก็จะมีแต่งานด้าน back-end หรือ server side
แต่พอได้มาจับ AngularJS JavaScript UI framework ที่รองรับการเขียน unit test ทำให้ผมเริ่มคิดกับเรื่อง unit test กับ UI แต่ยังไม่ได้มีโอกาสเริ่มสักที เพราะเรื่องนี้ค่อนข้างใหม่สำหรับผมมาก
แต่เชื่อไหมครับ พอเราเขียน JavaScript มากขึ้น พอแก้ตรงนั้นที ตรงนี้ที แล้วไม่มี unit test เวลาจะ deploy ก็ต้องมานั่ง manual test ดูว่า code ที่เพิ่ม ที่แก้ กระทบอะไรบ้าง กลายเป็นเรื่องที่น่าเบื่อมาก
มันคงเป็นเรื่องที่ดีไม่น้อย ถ้าเราสามารถลดปริมาณ manual test ลงให้น้อยที่สุด แต่เพิ่มปริมาณ unit test ให้มากขึ้น
ดังนั้น วันนี้ครับ เราจะมาดูกันว่า เราสามารถเขียน unit test ให้กับ JavaScript AngularJS ได้อย่างไร โดยในตอนนี้เราจะเริ่มจากการติดตั้งเครื่องมือ framework ที่จำเป็น และเขียน JavaScript unit test ง่ายๆ กันก่อน
ขั้นตอนต่างๆ เป็นดังนี้
ให้ไปที่ https://nodejs.org/en/ download version ที่ตรงกับเครื่องของเรา แล้วทำการติดตั้งให้เรียบร้อย หากติดตั้งได้ถูกต้องเราจะก็มีคำสั่ง npm มาให้ด้วย npm ย่อมากจาก node package manager เป็นตัวจัดการ library ต่างๆ และเครื่องมือตัวช่วยอื่นๆ สำหรับ node js project
ทดลองเปิด command line tool ใน Windows ก็ cmd หรือ terminal ใน mac แล้วทดลองใช้คำสั่งต่อไปนี้
>npm -version
3.6.0
หากผลลัพธ์แสดงตัวเลข version ของ npm ออกมา แสดงว่าเราได้ทำการติดตั้ง npm เรียบร้อยแล้วครับ
package.json file จะเอาไว้เก็บ config ต่างๆ ที่เกี่ยวกับ project และ library ต่างๆ ที่ต้องใช้ใน project เราจะใช้คำสั่ง npm init เพื่อสร้าง package.json ใน folder ที่เราเป็น root ของ project ยกตัวอย่างผมทำการเก็บ project ไว้ที่ D:\projects\beginning-angularjs-unit-test
เราก็ใช้ cmd เปิดที่ folder ของ project เราเลย พร้อมใช้คำสั่ง npm init ดังนี้
$ npm init
หลังจากที่เราได้ใช้งานคำสั่งนี้ด้วยการ enter จะมีข้อความต่างๆ แสดงขึ้นมาเพื่อถามเราเกี่ยวกับค่า setting ต่างๆ ใน project เราสามารถ enter ไปเรื่อยๆ เพื่อใช้ค่าที่ถูกตั้งมาให้ หรือพิมพ์เปลี่ยนได้ตามที่เราต้องการ สำหรับผมเองเปลี่ยนเพียง author ชื่อผู้สร้าง project นี้ครับ
$ npm install karma --save-dev
note
--save-dev ใช้สำหรับบันทึกชื่อตัว package เข้าไปที่ package.json ในส่วนของ devDependencies เพื่อแยกส่วนกันชัดเจนว่า package ตัวนี้ เราใช้เพื่อการ dev หรือ test เท่านั้นครับ
ส่วน --save จะเก็บชื่อ package ไว้ใน dependencies เป็น package ที่มีความจำเป็นในการ run application
package ทั้งหมดที่ถูกติดตั้งด้วยกรณีนี้ จะถูกเก็บใน folder node_modules
D:\projects\beginning-angularjs-unit-test> npm install karma-jasmine karma-phantomjs-launcher phantomjs-prebuilt jasmine-core --save-dev
จากคำสั่งที่ใช้ สังเกตได้ว่า เราติดตั้ง package ดังต่อไปนี้
เพื่อความสะดวกในการใช้งาน กล่าวคือให้ เราสามารถใช้งานคำสั่ง Karma ตรงๆ เข้าไปที่ cmd หรือ terminal เราต้องติดตั้ง Karma command line interface ก่อน ด้วยคำสั่งต่อไปนี้
$ npm install -g karma-cli
ก่อนเริ่มใช้งาน Karam เราต้องสร้าง config file ของ Karma ขึ้นมาก่อนโดยใชคำสั่งต่อไปนี้
D:\projects\beginning-angularjs-unit-test>karma init
เลือกตัวเลือกต่างๆ ดังต่อไปนี้
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine
Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no
Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> PhantomJS
>
What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> src/**/*.js
> spec/**/*.js
>
Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>
Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes
เราก็ได้ Karma cofig file ที่ชื่อว่า karma.config.js ไว้ใช้งาน ทดลอง run Karma ด้วยคำสั่งนี้เลย
$ karma start karma.conf.js
ผลลัพธ์การทำงาน
13 02 2016 11:32:29.775:WARN [watcher]: Pattern "D:/projects/beginning-angularjs-unit-test/src/**/*.js" does not match any file.
13 02 2016 11:32:29.780:WARN [watcher]: Pattern "D:/projects/beginning-angularjs-unit-test/spec/**/*.js" does not match any file.
13 02 2016 11:32:29.788:WARN [karma]: No captured browser, open http://localhost:9876/
13 02 2016 11:32:29.802:INFO [karma]: Karma v0.13.19 server started at http://localhost:9876/
13 02 2016 11:32:29.812:INFO [launcher]: Starting browser PhantomJS
13 02 2016 11:32:31.686:INFO [PhantomJS 2.1.1 (Windows 7 0.0.0)]: Connected on socket /#c-gaRtZ3Mlkk7WIYAAAA with id 98899492
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 0 of 0 ERROR (0.002 secs / 0 secs)
สังเกตที่ error บรรทัดที่ 1 และ 2 เนื่องจากเรายังไม่มี unit test ที่จะ test เลย ตรง out put จึงมี warning แสดงว่าไม่เจอ folder src และ spec ที่เราได้กำหนดไว้ตอน config Karma init
ทดลองเขียน unit test ง่ายๆ กันครับ สร้าง JavaScript file ชื่อว่า calculator.js ใน folder src และเพิ่มคำสั่งต่อไปนี้
src/calculator.js
function add (x, y) {
return x + y;
}
ต่อไปเราต้องการที่จะทดสอบว่า function add นี่ทำงานได้ถูกต้องหรือไป ให้เราสร้าง file ชื่อว่า calculatorSpec.js ใน folder spec และเพิ่มคำสั่งต่อไปนี้
spec/calculatorSpec.js
describe('calculator', function() {
it('should add two numbers', function() {
expect(add(1,2)).toBe(3);
});
});
เพื่อความสะดวกขึ้นไปอีกนิด แทนที่จะใช้คำสั่ง karma start karma.conf.js เราสามารถใช้คำสั่งผ่าน npm ได้แบบนี้เลย npm test
แต่เราต้องเข้าไปแก้ไข package.json section test ให้เป็นดังนี้
{
"name": "beginning-angularjs-unit-test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "karma start karma.conf.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/codesanook/beginning-angularjs-unit-test.git"
},
"author": "aaron",
"license": "ISC",
"bugs": {
"url": "https://github.com/codesanook/beginning-angularjs-unit-test/issues"
},
"homepage": "https://github.com/codesanook/beginning-angularjs-unit-test#readme",
"devDependencies": {
"jasmine-core": "^2.4.1",
"karma": "^0.13.19",
"karma-jasmine": "^0.3.7",
"karma-phantomjs-launcher": "^1.0.0",
"phantomjs-prebuilt": "^2.1.4"
},
"dependencies": {},
"description": ""
}
บรรทัดที่ 6 เราแก้ไขค่าให้ test script มีค่าเป็น "test": "karma start karma.conf.js"
ทดลอง run Karma อีกครั้งด้วยคำสั่งต่อไปนี้
$ npm test
ผลลัพธ์ที่ได้
13 02 2016 12:00:10.105:WARN [karma]: No captured browser, open http://localhost:9876/
13 02 2016 12:00:10.121:INFO [karma]: Karma v0.13.19 server started at http://localhost:9876/
13 02 2016 12:00:10.130:INFO [launcher]: Starting browser PhantomJS
13 02 2016 12:00:12.030:INFO [PhantomJS 2.1.1 (Windows 7 0.0.0)]: Connected on socket /#ViZub4yBgWkuicGLAAAA with id 89275194
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 1 of 1 SUCCESS (0.004 secs / 0.002 secs)
ที่บรรทัดที่ 5 บอกว่า Executed 1 of 1 SUCCESS บอกว่า function add ทำงานถูกต้องตามที่เราต้องการ
ลองแก้ calculatorSpec.js เป็นแบบนี้บ้าง
describe('calculator', function() {
it('should add two numbers', function() {
expect(add(1,2)).toBe(4);
});
});
กลับไปดูที่หน้าต่าง command line Karma ถูก run โดยอัตโนมัตครับ
13 02 2016 12:03:10.092:INFO [watcher]: Changed file "D:/projects/beginning-angularjs-unit-test/spec/calculatorSpec.js".
PhantomJS 2.1.1 (Windows 7 0.0.0) calculator should add two numbers FAILED
Expected 3 to be 4. D:/projects/beginning-angularjs-unit-test/spec/calculatorSpec.js:3:24
ในบทความนี้ เราได้เรียนรู้การติตตั้งเครื่องมือต่างๆ ที่จำเป็น และทดลองเขียน JavaScript unit test แบบง่ายๆ ในบทความต่อๆ ไป เราจะลองดูกันว่าเราจะเขียน unit test ให้กับ Angular Controller Service กันได้อย่างไรครับ
เมื่อโหลดไปแล้วใช้คำสั่ง npm install package ต่างๆ ก็จะโหลดให้โดยอัตโนมัติครับ