Unit Test 101 — มือใหม่หัดเขียนเทสต์ ด้วย Jest + Enzyme บน Next.js

Nat Nuthakul Nuthep
te<h @TDG
Published in
4 min readOct 9, 2019
Jest (by Facebook) + Enzyme (by Airbnb) + Next.js

Unit Test คืออะไรกันนะ ?

โค้ดข้าไม่ได้ผิดเว้ย ข้าน่ะระดับโปร ! (จริงหรือออพี่จ๋าา ~)

ปัญหาที่เกิดขึ้นบ่อยครั้งเวลาเรากำลังพัฒนา Project ก็คือการเจอ Bug หรือเกิด Error ขึ้นมา แต่ไม่สามารถตรัสรู้ได้ว่ามันพังมาจากจุดไหน เขียนโค้ดไปเป็นพันๆบรรทัด มีไฟล์อีกเป็นสิบ กว่าจะหาเจอบางทีก็ใช้เวลากันเป็นวัน หรือถ้าโชคร้ายจริงๆ จิ้งจกทัก ก้าวขาผิดข้าง ก่อนออกจากบ้าน ก็ Investigate กันเป็นอาทิตย์ ข้าม sprint แล้วก็ยังไม่เจอไอ้เจ้า Bug ตัวร้ายนี่ซักที …

เราจึงต้องสร้างตัวช่วย มาเป็นเครื่องทุ่นแรงในการตรวจสอบพวก Error ยิบย่อยที่อาจมองไม่เห็นด้วยตา (แต่สามารถมองเห็นได้ด้วยใจ ตึ่งโป๊ะ !) สามารถมองเห็นได้ด้วยใจจริงๆนะ คือต้องมีใจที่จะเขียน Unit Test ขึ้นมานี่แหละ ฮ่าๆ

ก่อนอื่นเราต้องมาทำความรู้จักกับคำว่า Unit Test กันก่อน ว่ามันคืออะไร ทำงานยังไง และมีประโยชน์อย่างไรบ้าง

  • Unit Test คือ การทดสอบเล็กๆในขอบเขตจำกัด เป็นการทดสอบส่วนประกอบที่เล็กที่สุดของ Project หรือเพียงระดับ Components เพื่อเช็คความถูกต้องในการทำงาน
  • Unit Test สามารถทำให้เจอต้นตอของปัญหา (Failure Isolation) ได้ดีขึ้นอย่างมาก เนื่องจากถ้าเราเห็น Test พังเมื่อไหร่ เราจะสามารถรู้ได้เลยว่า มันพังมาจากจุดใด หรือ Function ไหน อยู่ที่ Class ใด
  • การตั้งชื่อ Unit Test ที่ดี จะสามารถทำให้คุณรู้ได้ทันที ว่าต้องไปตรวจสอบหรือแก้ตัว Code ที่บรรทัดที่เท่าไหร่กันเลยแหละ !

Jest คืออะไร ไว้ทำอะไรนะ ?

“ Delightful JavaScript Testing ”

Jest คือ ตัวทำ Test หรือ Test Runner ซึ่งถูกพัฒนาโดย Facebook ที่จะทำให้ชีวิตในการเขียนเทสต์ของคุณง่ายขึ้นมากกกกก

Jest คือ Mocking library ทำให้เราไม่จำเป็นต้องลง Library เพิ่ม เช่น sinon, proxyquire และใดใดก็ตาม ให้ปวดหัววุ่นวาย เป็นตัวจบที่ครบครัน

Jest คือ Assertion library เราจึงไม่ต้องลง Chai, Should.js หรืออื่นๆ มาเพื่อทำ Assertion เลยจ้า ครบจบในตัวเดียวว เยี่ยมไปเลย !

ที่สำคัญ ! มันได้ลดการตั้งค่าที่ซับซ้อนและเยอะแยะวุ่นวายออกไป ตั้งค่าเพียงนิด ชีวิตจิตแจ่มใส เมื่อใช้ Jest !! 🤩 เป็นไงเจ๋งใช่ไหมล่าาา ?

Enzyme ที่เขาว่ากันว่า เป็นคนรักเดียวใจเดียว

Enzyme คือ เครื่องมือในการทดสอบ Javascript ที่สามารถใช้ได้กับแค่ React เท่านั้น ! (รัก React มาก ไม่นอกใจด้วยยย)

Enzyme ถูกพัฒนาโดย Airbnb มาเพื่อ Mount Components บน React — ซึ่งจุดเด่นของเจ้านี่ ก็คือการที่มันเข้ามาช่วยในทำ Assertions (ตรวจสอบการทำงาน) Manipulations (ตรวจสอบการควบคุม) และ Traversals (ตรวจสอบการข้ามผ่าน) ของ Output บน Components ได้อย่างครบถ้วน เพียงแค่คุณโบกนิดสะบัดหน่อยยย ฮ่าาๆ 🧙🏻‍♀️

ทำไมถึงเลือกใช้ Jest + Enzyme บน Next.js

ที่จริงแล้ว Enzyme นั้นไม่สามารถ Going Solo lo lo ~ แบบ Jennie Kim ได้ จำเป็นต้องทำงานร่วมกับ Test Runner เท่านั้น ! ซึ่งเจ้านี่นั้นก็สามารถทำงานร่วมกัน Test Runner ได้หลายเจ้ามากๆ นอกเหนือจาก Jest เช่น Webpack, Mocha และอีกมากมายก่ายกอง สามารถดูรายละเอียดเพิ่มเติมได้ ที่นี่

ส่วน Jest นั้น ไม่จำเป็นต้องทำงานร่วมกับ Enzyme ก็ได้จ่ะ เพราะสามารถจะใช้งานร่วมกับ Test Tools ได้มากมายสุดแล้วแต่ใจเธอเลย .. ตัวนี้มาแรง สัญชาติญาณบอก

และที่สำคัญ ! เจ้าสองตัวนี้เนื้อหอมมากก กอไก่ พันล้านตัว .. ทั้ง Document ก็มีให้อ่านเพียบ Community ที่ค่อยช่วยกันแนะนำอีกบึม เหล่าโอเอซิสอุดมสมบูรณ์ขนาดนี้ อดใจไม่ให้ใช้ยังไงไหวเอ่ยย !

มาเริ่มทำ Unit Test แบบเบื้องต้นกันเถอะ Let’s Go !

Everywhere Everyday with Unit Test กันแบบยั่วๆ บดๆ จ้าา
  • ขั้นตอนแรกเริ่มจาก การติดตั้ง Jest และ Enzyme ลงบน Project ที่เราต้องการทำ Unit test — โดยเปิด Terminal บน Code editor ขึ้นมาแล้วพิมพ์ตามด้านล่างได้เลย
npm install jest babel-jest enzyme enzyme-adapter-react-16 --save-dev

หลังจากติดตั้งเสร็จ จะมาถึง การตั้งค่า Config

  • สร้างโฟลเดอร์ configs > สร้างไฟล์ enzyme.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
  • สร้างไฟล์ jest.config.js ไว้บน Root directory ของเรา
module.exports = {setupFilesAfterEnv: ['./configs/enzyme']};
  • สร้างไฟล์ใหม่ลงบนโฟลเดอร์ pages > Natty.js (ตัวอย่าง) สร้างเพื่อทดสอบการทำงานของ Jest และ Enzyme
import React, { Component } from 'react';function Natty() {
return (
<div>
<h1>Hello Natty</h1>
</div>
);
}
export default Natty;
  • สร้างโฟลเดอร์ __tests__ ลงในส่วนที่เราต้องการจะทำเทสต์ ในที่นี้คือส่วน pages
รูปแบบการสร้าง Unit Test เพื่อตรสวจสอบไฟล์ Natty.js
  • สร้างไฟล์ บน โฟลเดอร์ __tests__ > Natty.test.js
import React from 'react'
import Natty from '../Natty'
import { shallow, mount } from 'enzyme'
describe("Natty component", () => { test("it's renders", () => {
const wrapper = shallow(<Natty />);
expect(wrapper.exists()).toBe(true);

});
});

เมื่อติดตั้ง และตั้งค่าทุกอย่างเสร็จแล้วนั้น ก็ Run Test กันเลย อย่ารอช้าาาาาา

ก่อนอื่น อย่าลืมไปตั้งค่าที่ไฟล์ Package.json กันก่อนเด้ออออ (ดูตามด้านล่างได้เลยจ่ะพี่จ๋าา)

"scripts": {
...
...
"test": "jest --watch",
"test-coverage": "jest --coverage"
}

จากนั้น ทำการพิมพ์คำสั่งเพื่อ Run Test ได้ตามข้างล่างนี้เลย

npm run test
Test -watch แบบต้นตำรับของพวกเรา

อีกแบบคือ Run Test แบบ Coverage — จะเป็นการแสดงผลลัพธ์ที่สวยใสซาบซ่า

npm run test-coverage

ผลลัพธ์ที่ได้ออกมา จะสวยงามเช่นนี้แล พี่เอย ~

Test -coverage ผลเทสต์สีเขียวอื๋ออ ~ มันช่างเจิดจ้าซะเหลือเกิน

สรุปสุดท้ายแต่ไม่ท้ายสุด !

เหล่า Dev ทั้งหลาย จง “ยืดอกพกเกราะ ” ไม่งั้นศพจะไม่สวยเหมียนหมาแน่ๆ

การทำ Unit Test นั้นเหมือนเป็นการสร้างเกราะป้องกันให้กับเหล่า Dev ทั้งหลาย ให้สามารถหายใจหายคอได้คล่องมากขึ้น เวลาที่พบเจอ Bug ทั้งหลายแหล่ ..

อีกทั้งปัจจุบันนี้ก็ยังมี Tools ให้เราเลือกใช้กันตามศรัทธาได้เลย ถูกใจค่ายไหน ชอบค่ายไหน ก็เลือกเอาตาม Style ที่คุณชื่นชม ~ เราจะไม่ขอตัดสินว่าตัวไหนดีกว่ากันเนอะ หากสี Logo ค่ายใดถูกโฉลกกับคุณก็อาจจะทำให้เกิด Bug น้อยลง ก็เป็นด้ายยย ~ (แนทจิตสัมผัสมาเองจย้าา คิกค้าก)

แต่ที่เลือกใช้ Jest + Enzyme ก็เพราะว่ามีคนใช้เยอะนั่นเอง LoL 🤪 มี Document ให้อ่านเยอะ โดยเฉพาะเวลาเจอปัญหาก็ Search โลดดด มีคนมาคอยช่วยให้คำแนะนำพร้อมหาทางแก้ให้เยอะแยะเลยยจ้าแม่ ~

ประหยัดเวลาในการหาต้นตอของ Bug และ Error นั้นๆ (จะได้มีเวลาไปดื่ม🍺 เพิ่มขึ้น ฮ่าาาๆ) และก็จะสามารถหา Solution มาแก้ปัญหาได้รวดเร็วมากยิ่งขึ้นนด้วยนาจาา

สำหรับในส่วนการทำ snapshots นั้น เอาไว้เจอกันในครั้งหน้าเน้อออ เขียนครั้งแรกโพสต์มันก็ยาวเกินไปแล้วว แหะๆ

Keep Coding and Writing Tests นะจ้ะทู้กคนน ! ไว้เจอกันใหม่ See ya ❤ ~

--

--

Nat Nuthakul Nuthep
te<h @TDG

Commu Geek Insomnia | Frontend Dev 💻 | Beer Lovers 🍺 | • nothing comes of nothing • 🖤