สรุปบทที่ 6 เรื่อง Covering Our Bases with Unit Test

จากหนังสือ The Way of the Web Tester


เนื้อหาในบทนี้จะมุ่งเน้นไปที่ฐานของพีระมิดที่เราได้เห็นกันมาในบทก่อนๆ ซึ่งจะมุ่งเน้นไปในการทำงานในฝั่งของ Developers แต่นักทดสอบก็สามารถเรียนรู้ได้และจะเปิดมุมมองให้นักทดสอบเข้าใกล้กับนักพัฒนามากขึ้น

สิ่งที่หวังว่าผู้อ่านจะได้หลังจากอ่านบทความนี้
- รู้จักกับ Unit Tests ในเชิงลึกขึ้น
- รู้ว่า Unit Test เขียนอย่างไร
- ทำไมมันต้องอยู่ฐานสุดของพีระมิดด้วยนะ

Everything Is Awesome

เมื่อเราต้องแก้ปัญหาโดยการใช้ UI Tests ในการทดสอบต้องอาศัยการทำงานหลายๆส่วนในการทดสอบ ทำให้การทดสอบของเราดูมีขนาดใหญ่และยุ่งยากพอสมควร และนี่เองอาจทำให้การทำงานเกิดข้อผิดพลาดได้ เหมือนกับรูปด้านล่างนี้ ที่เราต้องตอกตะปูที่มีขนาดใหญ่ ค้อนเราก็ต้องมีขนาดใหญ่ด้วย


The Challenge with UI Test

เมื่อระบบที่เราทดสอบมีขนาดใหญ่ขึ้นจากที่เราใช้เวลาในการ Build ในระดับวินาทีหรือนาทีก็อาจจะเปลี่ยนเป็นใช้เวลาเป็นสิบนาทีหรือชั่วโมงเลยทีเดียว และยังส่งผลให้การทดสอบมีโอกาสที่จะมีปัญหามากขึ้น ดังรูปด้านล่าง

แต่ก็ไม่ได้หมายความว่าการทดสอบแบบ UI Tests ไม่ดีนะ แต่สำหรับนักพัฒนาอาจจะต้องการการทดสอบที่ให้ผลลัพธ์ที่รวดเร็วกว่าและมีความราบรื่นในการทำงานมากกว่า

UI Tests And Unit Tests

ที่จริงแล้ว UI Tests กับ Unit Tests ไม่สามารถนำมาเปรียบเทียบกันตรงๆได้เพราะถ้ามองจากประโยชน์ในการใช้งานแล้วก็มีความสำคัญทั้ง 2 รูปแบบแต่ในบทความนี้จะต้องการสื่อว่า ในระบบที่เราทดสอบกันนั้นส่วนไหนที่ในระดับของ Unit Test เข้าถึงก็ควรจะทำให้ได้มากที่สุด โดยให้เหตุผลดังนี้

ดังรูปด้านบน แสดงให้เห็นว่า UI Tests มีการทำงานที่ช้า ซึ่งสิ่งที่ทดสอบใน Unit Tests ใช้เวลาในระดับของ milliseconds แต่เมื่อไปทดสอบในระดับของ UI Tests นั้นอาจใช้เวลาในระดับของ seconds เลยทีเดียว

อีกอย่างคือ UI Tests มีความแน่นอนต่ำกว่า Unit Tests เพราะผลลัพธ์ที่ได้ออกมานั้นไม่มีความสม่ำเสมอในบางครั้งที่ทดสอบอาจจะสถานะเป็น Pass หรือครั้งใดครั้งหนึ่งอาจจะมีสถานะเป็น Fail ก็ได้ เพราะในการทดสอบในระดับของ UI Tests นั้นมีปัจจัยในการทดสอบหลายอย่าง

ในหนังสือยังบอกอีกว่าการทดสอบแบบ end-to-end เนี่ยก็เหมือนกับการหาเข็มในกองหญ้า ซึ่งการทดสอบแบบ UI Tests เพียงอย่างเดียวคงไม่เพียงพอเรายังต้องการการทดสอบที่ตอบโจทย์เรื่อง ความรวดเร็ว,ความประหยัด,ความแม่นยำ และให้ผลลัพธ์ที่รวดเร็วอยู่

Enter the Unit Tests

Unit Tests คือการทดสอบในระดับของ Method ของนักพัฒนา โดยจะต่างที่ Unit Test มีขนาดเล็กและมีความรวดเร็วกว่า UI Tests และ Integration Tests และจะให้ผลลัพธ์ที่แม่นยำกว่า เช่น ระบบที่มี Business Logic


How They Work

จากโค้ดด้านบนเป็น Method หนึ่งที่โดยลูกค้าแต่ละจะมีระดับของภาษีแตกต่างกัน โดยจะแบ่งไว้ในโค้ด ส่วน function ในการทดสอบจะถูกแบ่งไว้ที่ Functionality want to test ดังรูป ซึ่งสิ่งที่ควรมองในขณะที่เขียน Unit Test

Happy Paths => Method ที่เขียนทำงานถูกต้องทั้งหมด ที่อยู่ภายใต้ Conditions
Special Cases => เคสอื่นๆที่ทำงานใน Method และจะมี Edge case รวมอยู่ในส่วนนี้ด้วย
Exceptions => เคสที่รองรับข้อผิดพลาด และอาจทำให้การทำงานหยุดชะงัก
Program logic and Flow => มุมมองด้าน Programming, Logic และ Flow การทำงานต่างๆ
Anything else! => สิ่งที่ส่งผลให้เรามั่นใจว่า Method จะทำงานได้อย่างถูกต้อง

โดยในส่วนนี้เราจะแบ่ง cases ใน Method เพื่อที่จะนำไปทดสอบในระดับของ Unit Tests และจะมีรูปแบบการเขียนโค้ดเพื่อทดสอบดังนี้

โดยในส่วนโค้ดด้านบนก็จะทดสอบตามประเภทที่เราได้แยกไว้


เราจะรู้ได้อย่างไรว่าสิ่งที่เราเขียนเพียงพอต่อการทดสอบแล้ว…?

  • Make Sure It Works => ตรวจสอบให้แน่ใจ หรืออาจมีการสมมติการทำงานต่างๆของ Method ด้วย
  • Test Everything That Could Possibly Break => ทดสอบทุกอย่างที่อาจทำให้การทำงานหยุดหรือเกิดข้อผิดพลาดได้
  • Write Your Tests First => การเริ่มเขียนการทดสอบในส่วนแรกๆอาจจะทำคล้ายๆ TDD คือจะเขียนในส่วนของ case fail ก่อนแล้วค่อยมาเขียนในส่วนที่เป็น case pass

สรุปท้ายบทความ

  • เหตุผลที่ Unit Tests อยู่ในส่วนของฐานพีระมิดเพราะ เป็นการทดสอบที่มีส่วนย่อยค่อนข้างเยอะ จึงมีขนาดใหญ่
  • Unit Test มีความรวดเร็วอย่างมากและมีการ feedback ที่รวดเร็ว
  • มันทดสอบในระดับ local จึงมีความเร็วและแม่นยำ
  • สามารถเข้าถึง functions ที่ยากต่อการเข้าถึง เมื่อเราใช้รูปแบบการทดสอบในแบบอื่นๆ

Reference : https://pragprog.com/book/jrtest/the-way-of-the-web-tester