Angular Testing part 4
เตรียม Angular project ให้พร้อม ให้รู้ว่ามันใช้ Karma Test Runner และจัดการเรื่อง configuration testing แก่เรา
ใกล้ความจริงเข้ามาแล้ว จากเดิมที่เราได้รู้จักและเรียนรู้
- Jasmine เพื่อเขียน Unit Test
- Jasmine Report ใช้ jasmine-spec-reporter เพื่อแสดงชื่อ spec ที่ทดสอบ
- และ Code Coverage ใช้ nyc เพื่อชี้วัดการครอบคลุมของ Test กับโค้ดโปรแกรม
หนนี้เราจะมา Hello กับจ้าวที่เรียกตัวเองว่า Test Runner ชื่อ Karma ครับ
Test Runner คืออะไร
ง่ายๆเลยคือ Test ที่สามารถทำงานได้เองโดยเราไม่ต้องสั่งทุกรอบ อื่ม…กำปั้นทุบดินมากไปใช่ไหม ก็ runner คือนักวิ่ง ส่วน test ก็แปลว่าทดสอบ รวมเป็น “นักวิ่งทดสอบ” มันก็จะวิ่งทดสอบของมันไปเรื่อยๆ เมื่อ Unit Test เปลี่ยนแปลงไม่ว่าจะแก้ไข เพิ่มหรือลบ มันก็จะเริ่มกระบวนการทดสอบใหม่ตั้งแต่ต้น (จริงๆกำหนดได้ว่าแค่ไหน) เพื่อรับประกันว่าที่ทำไปนั้นไม่ทำให้โปรแกรมพังนะ
ดีต่อใจใช่ไหมล่ะ
Karma — a test runner that fits all our needs.
Karma บอกว่าตนเป็น Test Runner ก็แสดงว่ามันต้องสวมระบบอัตโนมัตินี้ด้วยวิธีการบางประการ
หัวใจของ Karma
คือผลของการทดสอบเป็นประโยชน์กับนักพัฒนามากที่สุด ประโยชน์ในที่นี้ก็คือชิ้นงานหรือโปรแกรมที่ทำ สามารถทำได้เร็วและดี กล่าวคือเป็นไปตาม requirement ทำให้มั่นใจว่าครบถ้วน ไม่ต้องจดต้องจำว่ามันมี logic แบบนั้นแบบนี้ โดยให้ Karma ดูแลการรายงานผล (feedback) ทั้งหมดนั้นให้ นักพัฒนาก็ไปจ้ำบ๊ะกับ spec หรือ Unit Test ได้แบบสุดกำลังเกิด
The main goal for Karma is to bring a productive testing environment to developers. The environment being one where they don’t have to set up loads of configurations, but rather a place where developers can just write the code and get instant feedback from their tests. Because getting quick feedback is what makes you productive and creative.
สิ่งที่ Karma ทำให้
เมื่อถูกเรียกให้ทำงาน
- Karma จะมองหาและอ่าน configuration
- มันจะเรียก web server ของมันเองให้ทำงาน พร้อมกันนี้เหล่า Browser รอคอยการ reconnection ด้วย websocket
- จากนั้นการ Test จะเริ่มขึ้นโดยให้ Browser เรียกมายังหน้าแรก ซึ่งหน้านี้มีกลไกการเรียกใช้งาน Test framework ต่อไป
จริงๆตั้งใจจะนำเพื่อนๆไปรู้จัก Karma แบบเพียว config ก่อน ทว่าเมื่อลองได้ทำแล้วปรากฏว่าต้องใช้เวลาจัดการ configuration พอสมควร ทั้งยังต้อง research ความเข้ากันได้ของ lib อีกไม่น้อย เรื่องนี้ผมตัดสินใจว่ายกให้เป็นหน้าที่ของผู้เชี่ยวชาญเขาดีกว่า
init project
Angular project ขณะนี้เวอร์ชันที่ 8 แล้ว เหมือนเดิมเราจะทำเรื่อง contacts แบบรายการบุคคลติดต่อในโทรศัทพ์ ดังนั้นใครที่ตามผมมาตั้งแต่ part แรกของเรื่องนี้ ให้จัดการลบของใน contacts ออกให้หมด เราจะเทโปรเจกต์ Angular ลงไปแทน
หากว่าอยู่ root project (ที่ contacts folder) ให้ cd .. ออกมาก่อน จากนั้นสร้าง Angular project ชื่อ contacts (ชื่อเดิมนี่แหละ) ตามรูป
เสร็จแล้ว cd เข้าไปใน contacts project อีกครั้ง
cd contacts
แล้วรัน
ng s
ที่ Browser ครับ
Test Reporter
เปิดอีก Terminal ขึ้นมาครับ cd ไปที่ project เรา (contacts) หนนี้เราจะรัน Test ที่มันเขียนไว้แล้ว
ng test
สวยงามใช่ไหมครับ มี Browser แสดงผลการทดสอบให้ด้วย สมกับที่ Karma ได้คุยไว้
อ่าว แล้วถ้าไม่อยากได้ Browser ล่ะ แค่ Terminal ก็พอ? คำตอบ ก็ได้ จาก root project เปิดไฟล์ karma.conf.js บรรทัดที่เขียนว่า
browsers: ['Chrome'],
แก้ไขเป็น
browsers: ['ChromeHeadless'],
จากนั้น ctrl + c ยกเลิกแล้วรัน ng test ใหม่ ผลลัพธ์ก็จะปรากฏแค่ Terminal อย่างเดียว
Code Coverage
ทีนี้มาดู Code Coverage กันบ้าง ให้เปิดอีก Terminal ขึ้นมา จากนั้น cd เข้าไปที่ project แล้วพิมพ์
ng test --watch=false --code-coverage
ธรรมดาที่ไหน Angular project จัดเตรียมให้พร้อมสรรพ!
คำสั่งนี้จะสร้าง folder ชื่อ coverage ให้เราเปิดเข้าไป แล้วคัดลอก path ของไฟล์ index.html ไปวางไว้บน Address bar ของ Browser
ถึงตรงนี้จึงสรุปได้ว่า Angular project ได้จัดการ config เจ้า Karma และ Jasmine พร้อมกับ Code Coverage ไว้ให้หมดแล้ว ง่ายดีใช่ไหมล่ะ
All test files
โปรดสังเกตผลของ Code Coverage ข้างต้น มันมองไปที่ folder ชื่อ src และ src/app คำถามคือ ไฟล์ config นี้อยู่ที่ไหน? คำตอบ อยู่ที่ไฟล์ชื่อ angular.json
จาก root project เปิดไฟล์ angular.json มองไปตรงส่วนที่เขียนว่า test > options
"test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js",
...
จะมี main ซึ่งระบุว่า src/test.ts
ดังนั้นจาก root project มองหา folder ชื่อ src ในนี้ต้องมี test.ts เปิดดูครับ
ไฟล์ test.ts บรรทัดที่เขียนว่า
// Then we find all the tests.const context = require.context('./', true, /\.spec\.ts$/);
ก็คือมองหาทุกไฟล์ที่มีชื่อลงท้ายว่า .spec.ts มาทำ Test นั่นเอง
เยี่ยม ถือว่ารู้เรื่อง ฉะนั้นเมื่อแกะเข้าไปที่ root project ตามด้วย src folder ตามด้วย app folder เราก็จะพบกับไฟล์ชื่อ app.component.spec.ts เป็นไฟล์ Test ของเรา
src/app/app.component.spec.ts
อีกครั้งหนึ่ง กลับไปดูผลของ Code Coverage อีกที
แล้ว src folder มีไฟล์ที่ลงท้ายด้วย .spec.ts ด้วยหรือเปล่า? คำตอบ ไม่มี (มีแต่ test.ts อยู่ภายใน)
อ่าว แล้วถ้าไม่อยากได้ src ล่ะ คืออยากได้ clean clean เฉพาะที่ลงท้ายด้วย .spec.ts เท่านั้น? คำตอบ ก็ให้ไปเปิดไฟล์ angular.json ส่วนของ test > options ที่เดิม
"test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js",...
ให้เพิ่ม codeCoverageExclude ระบุไปว่าไม่เอา src/test.ts
"test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", "codeCoverageExclude": [ "src/test.ts" ],...
แล้วรัน
ng test --watch=false --code-coverage
ทีนี้กลับไปจัดการกับ app.component.html เพราะเราต้องการ clear หน้านี้ให้ว่างเปล่า ลบทุกสิ่งอย่างในหน้านี้ออกให้หมด
เมื่อไม่มี content ใดๆแล้วก็ลบ Test ใน app.component.spec.ts ออกด้วยเช่นกัน
หากรัน ng test ไว้อยู่ให้ ctrl + c ยกเลิกแล้วรันใหม่
เช่นกัน รัน Code Coverage ใหม่อีกครั้ง
ผลลัพธ์
สรุป
Angular project จัดการ config เรื่องของ Tests ให้แล้วด้วย Karma ซึ่งจะแสดงผลลัพธ์การทดสอบ Unit Test (ผลการ Test แต่ละ spec) บน Browser รวมถึงเรื่อง Code Coverage โดยมองหาจากไฟล์ที่มีชื่อลงท้ายเป็น .spec.ts ทั้งหมดครับ
part หน้าเรามาดูเรื่อง TDD กับโปรเจกต์นี้กันต่อ ใช้ TDD สร้าง contact model ต่อด้วย contact component