กลับไปหน้าบทความ
#Unit Test#Table-Driven Test#Software Testing#Go#คุณภาพซอฟต์แวร์

Table-Driven Test เทคนิคเขียน Unit Test ให้สั้น กระชับ และเพิ่มเคสง่าย

Table-Driven Test คือแนวทางจัดข้อมูลทดสอบให้อยู่ในตารางเดียว แล้วใช้ลูปทดสอบทุกเคสอัตโนมัติ ช่วยลดโค้ดซ้ำ เพิ่มความครอบคลุม และทำให้ดูแลชุดทดสอบได้ง่ายขึ้นอย่างชัดเจน

24 พฤษภาคม 2569อ่านประมาณ 2 นาที

แชร์บทความ

Table-Driven Test เทคนิคเขียน Unit Test ให้สั้น กระชับ และเพิ่มเคสง่าย

Table-Driven Test เทคนิคเขียน Unit Test ให้สั้น กระชับ และเพิ่มเคสง่าย

การเขียน Unit Test แบบแยกทีละเคสอาจเริ่มต้นได้ง่าย แต่เมื่อจำนวนกรณีทดสอบเพิ่มขึ้น ไฟล์ทดสอบก็มักยาวขึ้น ซ้ำขึ้น และดูแลได้ยากขึ้นตามไปด้วย ปัญหานี้เกิดขึ้นกับหลายทีม โดยเฉพาะในงานที่มีรูปแบบการทดสอบคล้ายกัน แต่เปลี่ยนเพียงค่า input และผลลัพธ์ที่คาดหวัง

Table-Driven Test เป็นเทคนิคที่ช่วยแก้ปัญหานี้ได้อย่างตรงจุด โดยนำข้อมูลทดสอบทั้งหมดมารวมไว้ในโครงสร้างเดียว เช่น ตาราง รายการ หรือชุดข้อมูล จากนั้นให้ตัวทดสอบหนึ่งชุดวนรันทดสอบทุกกรณีโดยอัตโนมัติ ผลลัพธ์คือโค้ดสั้นลง อ่านง่ายขึ้น และเพิ่มเคสใหม่ได้สะดวกมาก

Table-Driven Test คืออะไร

แนวคิดหลักของ Table-Driven Test คือการแยก “ข้อมูลทดสอบ” ออกจาก “ตรรกะของการทดสอบ” อย่างชัดเจน

  • ข้อมูลทดสอบมีหน้าที่ระบุว่าใส่อะไรเข้าไป
  • ผลลัพธ์ที่คาดหวังมีหน้าที่บอกว่าควรได้อะไรออกมา
  • ตัว test มีหน้าที่วนลูป รันฟังก์ชัน และเปรียบเทียบผลเท่านั้น

แทนที่จะเขียน test 5 หรือ 10 อันที่มีโครงเหมือนกันทั้งหมด เราสามารถเขียน test เพียงชุดเดียว แล้วให้ข้อมูลในตารางเป็นตัวกำหนดว่าต้องทดสอบอะไรบ้าง

จุดเด่นที่ทำให้หลายทีมเลือกใช้

ข้อดีของ Table-Driven Test มีหลายด้านและเห็นผลได้ค่อนข้างเร็ว

  • ลดโค้ดซ้ำที่เกิดจากการเขียน test รูปแบบเดิมหลายครั้ง
  • เพิ่มกรณีทดสอบใหม่ได้ง่าย เพียงเพิ่มแถวข้อมูลเข้าไป
  • มองเห็นภาพรวมของเคสทั้งหมดได้ทันทีในบล็อกเดียว
  • ลดโอกาสลืมเคสสำคัญ โดยเฉพาะเคสขอบหรือ edge case
  • ช่วยให้ reviewer ตรวจสอบความครอบคลุมของ test ได้เร็วขึ้น

เมื่อโค้ดทดสอบมีโครงสร้างที่เป็นระบบมากขึ้น ทีมก็จะขยายชุดทดสอบได้ง่ายขึ้นตามไปด้วย และนั่นมีผลโดยตรงต่อคุณภาพของซอฟต์แวร์

เหมาะกับงานประเภทไหน

Table-Driven Test เหมาะมากกับงานที่มีความสัมพันธ์ระหว่าง input และ output ชัดเจน เช่น

  • การคำนวณราคา
  • การตรวจสอบสิทธิ์
  • การจัดรูปแบบข้อความ
  • การตรวจสอบข้อมูลในฟอร์ม
  • การแปลงข้อมูลจาก API

งานลักษณะนี้มักมีเงื่อนไขย่อยหลายแบบ แต่รูปแบบของการทดสอบคล้ายกันมาก จึงเหมาะกับการรวมเป็นตารางเพื่อให้จัดการได้ง่ายกว่าเดิม

ตัวอย่างแนวคิดแบบง่าย

สมมติว่ามีฟังก์ชันสำหรับบวกเลข หากเขียนแบบเดิม อาจต้องสร้าง test แยกสำหรับการบวกเลขปกติ บวกเลขศูนย์ บวกเลขติดลบ หรือค่าที่มากผิดปกติ

แต่ถ้าใช้ Table-Driven Test เราสามารถสร้างตารางที่เก็บข้อมูลเช่น

  • ค่า a
  • ค่า b
  • ผลลัพธ์ที่คาดหวัง
  • ชื่อกรณีทดสอบ

จากนั้นใช้ test ตัวเดียววนทดสอบทุกแถวในตาราง ผลคือจำนวนบรรทัดลดลง แต่จำนวนเคสเพิ่มขึ้นได้โดยไม่ทำให้ไฟล์รก

เคล็ดลับสำคัญ: ตั้งชื่อแต่ละเคสให้ชัด

หนึ่งในเทคนิคที่ช่วยให้ Table-Driven Test ใช้งานได้ดีขึ้นมาก คือการตั้งชื่อให้แต่ละกรณีทดสอบ เช่น

  • บวกเลขปกติ
  • บวกเลขติดลบ
  • บวกเลขศูนย์
  • ค่ามากผิดปกติ

ประโยชน์ของการตั้งชื่อเคสคือ เมื่อทดสอบแล้วเกิดความล้มเหลว ระบบจะแสดงได้ทันทีว่าเคสใดมีปัญหา ทำให้นักพัฒนาไม่ต้องเสียเวลาไล่อ่านทั้งไฟล์เพื่อหาต้นตอของข้อผิดพลาด

ใช้ได้กับหลายภาษา ไม่ได้จำกัดแค่ Go

แม้ว่าแนวทางนี้จะได้รับความนิยมมากในภาษา Go เพราะสามารถใช้ slice ของ test case ได้อย่างกระชับและอ่านง่าย แต่จริง ๆ แล้วแนวคิดเดียวกันสามารถนำไปใช้ได้กับหลายภาษา

  • JavaScript สามารถใช้ array ของเคส และวนด้วย forEach
  • Python สามารถใช้ list of dicts
  • Java สามารถใช้ parameterized test
  • ภาษาอื่น ๆ ก็ประยุกต์ใช้ได้ในรูปแบบคล้ายกัน

ดังนั้น Table-Driven Test ไม่ใช่เทคนิคเฉพาะภาษา แต่เป็นรูปแบบความคิดในการออกแบบ test ให้เป็นระบบมากขึ้น

พลังของการใส่ Edge Case ตั้งแต่แรก

สิ่งที่ทำให้ Table-Driven Test มีประโยชน์มากขึ้นอีกระดับ คือการบังคับให้เราคิดถึง edge case อย่างเป็นระบบตั้งแต่ต้น เช่น

  • ค่าว่าง
  • ค่ายาวผิดปกติ
  • ข้อมูล null
  • ตัวอักษรพิเศษ
  • ค่าที่เกินขอบเขต

ในโลกจริง บั๊กจำนวนมากไม่ได้เกิดจากกรณีใช้งานปกติ แต่เกิดจากสถานการณ์มุม ๆ ที่ไม่มีใครลองก่อน deploy การจัด edge case ไว้ในตารางทดสอบตั้งแต่แรก จะช่วยลดโอกาสที่ปัญหาเหล่านี้หลุดไปถึง production

ทำไมคนรีวิวโค้ดถึงชอบแนวทางนี้

สำหรับการรีวิวโค้ด Table-Driven Test มีข้อได้เปรียบชัดเจน เพราะ reviewer สามารถเปิดมาแล้วเห็นรายการกรณีทดสอบทั้งหมดในจุดเดียว ทำให้ตรวจสอบได้รวดเร็วว่า

  • มีเคสหลักครบหรือไม่
  • มี edge case ที่สำคัญแล้วหรือยัง
  • มีกรณีที่ควรเพิ่มอีกหรือเปล่า

การสื่อสารระหว่างคนเขียนกับคนรีวิวจึงง่ายขึ้น และช่วยยกระดับมาตรฐานของชุดทดสอบในทีมได้ดี

วิธีเขียนให้สะอาดและดูแลง่าย

หากต้องการให้ Table-Driven Test อ่านง่ายจริง ควรแยกบทบาทของแต่ละส่วนให้ชัดเจน

  1. ส่วนข้อมูลทดสอบ ระบุ input และ expected output
  2. ส่วน logic ของ test ทำหน้าที่รันฟังก์ชันและตรวจผล
  3. หากมีขั้นตอนเตรียมข้อมูลที่ซับซ้อน ควรแยก helper function ออกมา

แนวทางนี้จะช่วยให้ไฟล์ทดสอบสะอาดขึ้น และลดความสับสนเวลาต้องกลับมาแก้ไขในอนาคต

ข้อควรระวังในการใช้งาน

แม้ Table-Driven Test จะมีข้อดีมาก แต่ก็มีสิ่งที่ควรระวังเช่นกัน คือไม่ควรพยายามยัดทุกอย่างลงในตารางจนอ่านยากเกินไป

ถ้าการเตรียมข้อมูลเริ่มซับซ้อนมาก หรือแต่ละกรณีมีเงื่อนไขเฉพาะแตกต่างกันมาก อาจต้องใช้ helper function หรือแยก test บางส่วนออกไป เพื่อคงความชัดเจนในการอ่าน

เป้าหมายของเทคนิคนี้ไม่ใช่แค่ลดจำนวนบรรทัด แต่คือการทำให้ test เข้าใจง่าย ขยายต่อได้ง่าย และยังคงสื่อความหมายได้ดี

เมื่อไรควรเริ่มใช้ Table-Driven Test

สัญญาณที่ชัดที่สุดคือ เมื่อ test ของคุณเริ่มมีรูปแบบซ้ำกันหลายครั้ง และสิ่งที่เปลี่ยนมีเพียง input กับ expected output เท่านั้น นั่นคือช่วงเวลาที่เหมาะมากในการเปลี่ยนมาใช้แนวคิดแบบ table-driven

ยิ่งระบบมีขนาดใหญ่ขึ้น เทคนิคเล็ก ๆ แบบนี้จะยิ่งให้ผลลัพธ์ที่ชัดเจน จาก test ที่เคยยาว กระจัดกระจาย และขยายยาก จะกลายเป็นชุดทดสอบที่สั้น กระชับ และจัดการได้เป็นระบบมากขึ้น

สรุป

Table-Driven Test เป็นเทคนิคที่เรียบง่ายแต่ทรงพลังสำหรับการเขียน Unit Test ช่วยลดโค้ดซ้ำ เพิ่มจำนวนเคสได้สะดวก มองเห็นภาพรวมของการทดสอบได้ดี และลดโอกาสที่บั๊กจากกรณีมุม ๆ จะหลุดไปถึง production

สำหรับมือใหม่ เทคนิคนี้คุ้มค่าต่อการฝึกมาก เพราะช่วยสร้างนิสัยการคิดเคสอย่างเป็นระบบ และทำให้การเขียน test ไม่น่าเบื่อเหมือนเดิม ส่วนสำหรับทีมที่ดูแลระบบขนาดใหญ่ แนวทางนี้ยิ่งช่วยให้การบำรุงรักษา test มีประสิทธิภาพและขยายต่อได้ง่ายในระยะยาว