สร้าง Code Coverage Report จากการรัน End-to-End Test ด้วย Cypress.io กันดีกว่า

Traitanit Huangsri
Cypress.io Thailand
4 min readJul 6, 2019

สวัสดีครับ ผมเชื่อว่าหลายคนที่เป็น Developer/QA น่าจะเคยเขียน Web Automation Test กันมาบ้าง ไม่ว่าจะเป็น Unit, Integration หรือแม้กระทั่ง End to End (E2E) Test ก็ตาม ซึ่งพอเราเขียน Test ปริมาณเยอะขึ้นเรื่อยๆ ก็มักจะเริ่มมีคำถามว่า

  • เอ๊ะ นี่เราเขียนเทสมากพอหรือยัง?
  • Test ที่เรามีอยู่มันไปแตะโค้ดที่เราต้องการจะเทสหมดแล้วหรือยัง?
  • มี Test Case ไหนที่เรายังไม่ได้เขียนให้ Cover อีกมั้ย?

คำถามนี้ถ้าใครที่เคยเขียน Unit Test มาก็คงจะตอบได้ไม่ยากนัก ก็แค่ทำ Code Coverage ก็รู้แล้วใช่ไหมครับ แต่สำหรับ End to End Test นั้นเป็นคำถามที่ตอบยากจริงๆ ครับ

ซึ่งถ้าใครที่ใช้ Cypress เป็น Framework สำหรับทำ E2E Test นั้น ขอบอกเลยว่าคุณตอบคำถามนี้ได้แล้วครับ โดยวันนี้เราสามารถสร้าง Code Coverage Report จากการทำ E2E Test ได้โดยการใช้ Cypress Code Coverage Plugin ที่เพิ่งจะ Released มาให้เราได้ใช้กันเมื่อเร็วๆ นี้เองครับ

สำหรับใครที่ยังไม่เคยเขียน Test ด้วย Cypress มาก่อน สามารถอ่านบทความด้านล่างนี้เพื่อทำความรู้จักและหัดเริ่มเขียน Test ด้วย Cypress ก่อนได้นะครับ

Demo Project

Project ที่ผมจะนำมาเป็นตัวอย่างในบทความนี้จะเป็น Todo App ง่ายๆ ซึ่งเขียนอยู่บน VueJS นะครับ

ซึ่งใน App ตัวอย่างตัวนี้ เราสามารถ Add Todo List ได้ด้วยการพิม Text เข้าไปใน Input Text แล้วกด Enter หลังจากนั้น App ก็จะ Save Todo List โชว์อยู่ด้านล่างพร้อมทั้งมีปุ่มให้เราสามารถลบ Todo List ของเราได้ด้วยครับ

Code Instrumentation

ก่อนจะไปพูดถึงการทำ Code Coverage ขอพูดถึง Concept ของ Code Instrumentation ก่อนครับ ซึ่ง Code Instrumentation คือวิธีการดูว่า Code ของเราแต่ละบรรทัดนั้นมีการถูกเรียกใช้มาทั้งหมดกี่ครั้ง และมีจุดไหนที่ไม่ถูกเรียกใช้งานบ้าง โดยเราจะต้องมี Counter คอยนับการ Call ทั้งหมดของทุก Statement ในแอพเรา ซึ่งบน Web Application นั้นมี Library ที่ทำหน้าที่นี้ได้ดีก็คือ Istanbul ซึ่งเจ้า Istanbul เนี่ยมันจะช่วย Instrument Code ของเราเพื่อสร้าง Code Coverage ให้เราอัตโนมัติโดยที่เราแค่สร้าง Configuration File นิดหน่อยก็ใช้งานได้แล้วครับ

Installation & Configuration

  1. Install babel-plugin-istanbul, istanbul-lib-coverage และ nyc
  • babel-plugin-istanbul คือ Babel plugin ที่ใช้ในการทำ Code Instrumentation ด้วย Istanbul ซึ่งสามารถทำงานร่วมกันได้ดีกับทั้ง Karma และ Mocha Test Runner (Cypress ใช้หลักการ Extend Mocha Framework มาใช้สำหรับการ Manage Test Case อีกทีนึงครับ เลยใช้งาน plugin ตัวนี้ได้โดยปริยาย)
  • istanbul-lib-coverage คือ Library ที่ Provide API ที่สามารถใช้อ่านค่า Code Coverage ที่สร้างโดย Istanbul ออกมาได้ครับ
  • nyc คือ Command Line Interface (CLI) ของ Istanbul ที่ใช้ในการ Generate Code Coverage Report ออกมาในรูปแบบต่างๆ เช่น HTML เป็นต้น
sh$ yarn add babel-plugin-istanbul istanbul-lib-coverage nyc

2. Install Cypress Code Coverage Plugin

sh$ yarn add cypress @cypress/code-coverage 

3. เพิ่ม Configuration เข้าไปในไฟล์ .babelrc

4. สร้าง Configuration File สำหรับ nyc ซึ่งในที่นี้ผมต้องการให้มัน Coverage ทั้งไฟล์ที่นามสกุล .js และ .vue เลยครับ

Config Cypress Code Coverage Plugin

เราจะต้องทำการเพิ่ม Code Coverage Plugin เข้าไปที่ไฟล์ cypress/plugins/index.js ก่อนนะครับ ซึ่งการเพิ่ม Code Coverage Plugin นั้นจะมีผลทำให้เทสรันได้ช้าลงด้วยนะครับ เพราะมันต้องเข้าไปทำการ Instrument Code ทั้งหมดเพื่อสร้าง Code Coverage ให้เรา แต่อย่างไรก็ดีทาง Cypress ก็กำลังพยายามที่จะ Improve Performance ตรงนี้อยู่ครับ สามารถติดตาม Issue นี้ได้ที่นี่ครับ

cypress/support/index.js
cypress/plugins/index.js

เขียน E2E Test ด้วย Cypress

ในโค้ดของ App Todo ของผมได้ทำการใส่ Data Attribute ไว้เป็นที่เรียบร้อยแล้วครับ ดังนั้นในโค้ด E2E Test ของผมจึงจะใช้ Data Attribute เป็น Locator ในการ Find Elements ครับ ซึ่งก็เป็น Practice ที่แนะนำสำหรับการเขียน E2E Test ในทุกๆ Project เลยนะครับ

เมื่อสั่งรัน Test ด้วย Cypress UI Test Runner ก็จะได้ผลออกมาเป็นแบบนี้ครับ

เมื่อเรา Expand Test Case ออกมาดูทีละ Step จะเห็นว่า Cypress ได้ทำการ Hook task ที่เข้าไปทำการ Read ค่า Code Coverage ออกมาจาก App เราให้หลังจากเทสรันเสร็จ และสร้าง coverageReport ให้เสร็จสรรพเลยครับ ซึ่งหลังจากที่เทสเรารันเสร็จแล้วเราก็จะเห็น folder coverage ถูกสร้างมาให้เราแล้วครับ​ ซึ่งด้านในก็จะมี HTML Report ให้เราสามารถเปิดดูบนเว็บได้แบบนี้เลยครับ

E2E Test Code Coverage (Statement) 100% สวยงามเลยครับ

ผมลอง Skip Test Case ข้อ Delete Todo (ข้อ 2) ออก เพื่อจะเช็คว่า Code Coverage มันทำงานถูกต้องมั้ย มันไม่ได้ Generate ผลลัพธ์ออกมา 100% ตลอดเวลาใช่มั้ย ผลที่ได้คือแบบนี้ครับ

Code Coverage (Statement) เหลือ 87.5% แล้ว

เราสามารถ Click เข้าไปดูได้ใน Report ได้เลยว่ามี Code ตรงไหนที่เรายังไม่ได้มีเทสบ้าง ดีงามสุดๆ ครับ

2x, 3x คือจำนวนครั้งที่มีการ Call Statement นั้น

แถบสีแดงๆ คือโค้ดที่ผมยังไม่ได้เขียนเทส Cover ไว้ นั่นก็คือ Function ที่ใช้ในการ Delete Todo นั่นเอง เห็นกันชัดๆ กันไปเลยครับ ก็เดี๋ยวต้องเอาเทสข้อนั้นกลับมารันใหม่ครับ ฮ่าๆ

Furthermore

จะเห็นได้ว่าเราสามารถสร้าง Code Coverage จากการรัน E2E Test บนเครื่องเราได้แล้ว เราก็สามารถต่อยอดวิธีการนี้ไปใช้กับระบบ Continuous Integration ได้เลยครับ ซึ่งตัว nycสามารถสร้าง Coverage Report ได้อีกหลาย Format รวมถึงสามารถ Merge Unit Test Coverage มารวมได้ด้วย ซึ่งมันจะช่วยให้เราสามารถดู​ Code Coverage Trend ทั้งหมดของ Project เราได้ เพื่อสร้างความมั่นใจ (Confidence) ให้กับเราว่า Product ของเรามี Quality และถูก Test มาอย่างดีนะครับ ไว้มีโอกาสผมจะมาเล่าวิธีการนำ Code Coverage ไปใช้บนระบบ Continuous Integration ให้ได้อ่านกันอีกทีนะครับ

Cypress ยังมี Feature ที่น่าสนใจน่าใช้อีกมากมาย สามารถมาแลกเปลี่ยนความรู้ หรือถามคำถามเกี่ยวกับการเขียน Test ด้วย Cypress กันได้ที่ Cypress Thailand Community ได้เลยนะครับ ยินดีต้อนรับทุกท่านครับ วันนี้ขอตัวก่อนนะครับ Happy Testing!

Example Code Coverage Report: https://nottyo.github.io/cypress-e2e-code-coverage/coverage/

Reference: https://docs.cypress.io/guides/tooling/code-coverage.html

--

--