มาทำ Unit Testing บน Javascript ด้วย Jest ตอนที่ 2 — API Testing

ว่าด้วยเรื่องการทดสอบ API Code จาก Javascript ด้วย Jest

Natthawat Boonchaiseree
Muze Innovation
4 min readMay 13, 2017

--

ทำไมต้องทำการทดสอบ API กันนะ

อ่านรายละเอียดจาก Link นี้ได้เลย

API Testing VS Unit Testing

  • บ่อยครั้งที่ API Testing เป็นการทดสอบที่ระดับการเชื่อมโยง (Interface Level) ระหว่าง Client กับ Service เอย หรือระหว่าง service กับ service ด้วยกันก็ย่อมได้ แล้วแต่จะนิยาม
  • API Testing อาจแตกต่างจาก Unit Testing โดยบางครั้งการทดสอบ API อาจ มองเป็นเรื่องของการรับส่งข้อมูลกันโดยไม่คำนึงถึงความถูกต้องก็ได้ แต่ Unit testing จะเป็นการทำการทดสอบ function งานที่เกี่ยวข้องโดยตรงกับ Business requirement ซึ่งแน่นอนว่าต้องถูกต้องเท่านั้น ไม่สามารถเท หรือทิ้ง หรือมองให้เป็น black-box ได้
  • บ่อยครั้งการทดสอบ API Testing อาจทดสอบในลักษณะ Failure test หรือ Stress Testing เพื่อทดสอบข้อจำกัดที่เกิดขึ้นต่างๆ ว่ากันง่ายๆก็คือ ยิงกันให้พังไปก็มี และหลังจากพังจากจัดการยังไง (Error Handling) ก็ว่ากันไปตามความสำคัญ
  • แต่อย่าลืม… อย่างไรก็ตาม อยู่ที่ข้อตกลงระหว่างการทำงานในทีมนะ
  • รายละเอียดเพิ่มเติมพิจารณาได้ Link นี้เลย

API Testing ทำไมต้อง Mock

  • ไม่ต้องมารอ API Response จากระบบอื่นๆที่เราไม่สามารถจัดการ หรือควบคุมง่ายๆได้เอง
  • ไม่ต้องมากังวล Rate Limit ที่เกิดจาก Infra หรือ Environment อื่นๆ
  • วัดกันตรงไปตรงมาว่า Code ที่เขียนใช้ได้จริง ไม่ได้จริง โดยไม่ต้องกลัวเรื่องปัจจัยรอบข้าง เช่น Dependency ต่างๆ
  • ไม่ต้องมานั่งทำงานจุกจิกกว่าจะได้ทดสอบ เช่นต้อง Login เอา Token มาก่อนจึงจะเริ่ม Run function ที่ต้องการทดสอบจริงๆได้ เป็นต้น

มาเริ่มลงมือกันเลยดีกว่า

Remark: ใน session ต่อไปนี้จะถอดความจากบทความของ hackernoon ซึ่งยกตัวอย่างได้ชัดเจนมาผสมผสานนะครับ

STEP 1: Setup Jest พิจารณาได้จากบทความก่อนหน้านี้

พิจารณารายละเอียดได้จากบทความนี้เลย มาทำ Unit Testing บน Javascript ด้วย Jest ตอนที่ 1 หรือถ้าผู้อ่านยังไม่อยาก setup อะไรมากมายอาจไปลองเล่นได้ที่นี่ครับ https://repl.it/languages/jest

STEP 2: ทำการ Setup project

โดยตัวอย่างนี้เราจะมาสร้าง ReactJS Application เพื่อใช้ทดสอบกัน โดยเริ่มจากการติดตั้ง create-react-app module ก่อน และทำการ run project ด้วย yarn กันได้เลย

เมื่อเรียบร้อยแล้วลองไปที่ localhost:3000 ควรจะขึ้นดังรูปนะ

จากนั้นตรงไปตรงมา run ทดสอบกันเลยด้วยคำสั่ง “yarn test” กัน

ผลลัพธ์ออกมาแล้ว

มาถึงจุดนี้ เครื่องไม้เครื่องมือพร้อมสำหรับการทดสอบละ ถัดไปเราจะมาเขียนตัวอย่าง API ง่ายๆเพื่อใช้ในการทดสอบกัน

STEP 3: ทดลองเขียน API เพื่อใช้ในการทดสอบ

ออกตัวก่อนโดย ณ จุดนี้ ชาว JS ทั้งหลายสามารถเลือก Library ที่ตนเองชอบได้ แต่ในบทความนี้ขอยกตัวอย่างการเขียน API ด้วย Library “rest” กัน (เน้นเอาง่าย เอาเร็ว ท่านผู้อ่านอาจลองค่ายอื่นๆเช่น ExpressJS, Kao หรือ Hapi ก็ได้ไม่มีประเด็น)

สร้าง Folder “src/api” ขึ้นมาใน project จากนั้นเพิ่มไฟล์ดังต่อไปนี้

  • App.js — Code ในหลักที่ใช้ในการทำงาน ซึ่งในที่นี้เราจะทำการล้าง code ที่ได้จาก react-create-app module ออกและทำงานตาม Function ที่ต้องการทดสอบ
  • github.js — Function ที่รับค่า user เพื่อดึงข้อมูลจาก Github กลับมา
  • request.js — ทำตัวเองเป็น Middleware สำหรับการยิง REST Protocol

ทดสอบการ run “yarn start” อีกครั้ง

จะได้ผลลัพธ์ซึ่งเป็นรายละเอียดของ Github ที่ public ออกมาดังต่อไปนี้

STEP 4: ลงมือทดสอบกันดีกว่า

เริ่มลงมือทำการเขียน code ที่ใช้สำหรับการทดสอบ โดยเราจะทำการทดสอบ function “getUser” จากไฟล์ github.js ให้ทำการสร้าง directory ชื่อว่า “__test__” ขึ้นมาที่ตำแหน่งเดียวกับไฟล์ github.js และจากนั้นทำการสร้างไฟล์ทดสอบ “gitbub.test.js” (ไฟล์ทดสอบไม่จำเป็นต้องอยู่ใน directory __test__ ก็ได้นะ) พิจารณาีรายละเอียดดังต่อไปนี้

อธิบายโจทย์ของการทดสอบข้างต้น ดังนี้

  • ให้เรียก function ‘getUser“ โดยใช้การ Promise โดยได้รับค่าข้อมูล user กลับมา โดยระบุให้ user ที่ใช้ในการทดสอบคือ ‘artama’
  • โดยคาดหวัง (expect) ว่า response (ตัวแปร data ที่ตอบกลับมา) ที่ได้ต้องมีการ defined ค่าเรียบร้อย ไม่มีค่าเป็น “undefined” ซึ่งเราจะระบุตาม references ของ Jest โดยใช้ function “toBedefined
  • และคาดหวังว่าค่า node “entity.name” ของ response จะต้องมีค่าเท่ากับ “Natthawat” (ชื่อผู้เขียนเอง) ซึ่งเราจะระบุตาม references ของ Jest โดยใช้ function “toEqual” นั่นเอง

ไม่รอช้า run ทดสอบกันอีกครั้ง “yarn test” จะเข้าสู่หน้า watch mode แต่ได้ผลลัพธ์ FAIL แจ้ง รายละเอียดดังรูป

FAIL!!! มาถึงจุดนี้ก็จะพบว่าเราในกรณีที่เรา run “yarn start” ปกติ code สามารถทำงานได้อย่างถูกต้อง แต่พอเรา run “yarn test” ค่าที่ได้รับกลับมาด้านบน ซึ่งคาดหวังว่าจะเป็น “Natthawat” กลับกลายเป็น “undefined” แน่นอนเพราะ Code ชุดนี้ทำงานได้บน Browser ซึ่งมีการระบุ user-agent ที่ชัดเจน นั่นเอง… -_-

มาถึงจุดนี้มี 2 ทางเลือกที่เราจะต้องไปต่อ

  1. ดั้นด้นทดสอบต่อไป ก็เพิ่ม user-agent หรือ header ที่จำเป็นมันเสีย หรือ!
  2. ใช้ Jest Mock สิครับ

แน่นอนบทความนี้เลือกข้อ 2 … ^_^

STEP 5: MOCK

เราจะสร้าง directory ชื่อว่า “__mock__” โดยภายใต้นั้นจะทำการสร้างไฟล์ “request.js” เข้าไป ซึ่งใช้ในการสร้าง Mockup data ขึ้นมานั่นเอง มาดู code กัน

ก้อน request ข้างบนจะล้อการทำงานคือมีการรับ “url” เข้าไป และเรียก library “Promise” โดย function request ตัวนี้จะมาทำงานแทน library “request” แต่จะเป็นการไปอ่านไฟล์ Mock data ใน path “./src/api/__mockData__/${userID}.json” ออกมานั่นเอง โดยผลลัพธ์ของ promise จะถูก resolve ออกมาเป็นก้อน data ที่ได้จาก “${userID}.json” นั่นเอง มาดูหน้าตาของ json file กัน

ด้วยความขี้เกียจปั้น data ก็ไปเอา data มาจาก response ของ browser ที่ทำงานปกติมากันดังรูป

สร้างไฟล์ userID.json ซึ่งในที่นี่ ID Github ของผมคือ “artama” จึงตั้งชื่อไฟล์ “artama.json” ซึ่ง ณ จุดนี้โครงสร้าง file และ directory จะได้ดังนี้

ย้อนกลับไปที่ file “github.test.js” เราจะใช้ request จาก ไฟล์ request.js ใน directory “__mock__” มาทำงานแทน โดยการเรียกคำสั่ง mock จาก Jest ดังนี้

จะได้ผลลัพธ์จากการทดสอบเป็นที่เรียบร้อยสมบูรณ์ดังรูป

ตัวอย่างไฟล์พิจารณเพิ่มเติมได้ที่ Github กันเลยครับ

สำหรับตอนต่อไปเราจะมาลองทำการทดสอบให้มากขึ้นอีกนิดใน feature อื่นของ Jest โปรดติดตามกันครับ

--

--