หากต้องการทดสอบหรือไม่ทดสอบ มุมมองทางเทคนิค

พิจารณาว่าคุณต้องการทดสอบอะไรและอะไรที่สามารถตัดออกได้

บทความก่อนหน้านี้พูดถึงข้อมูลเบื้องต้นเกี่ยวกับกรอบการทดสอบและสิ่งที่ควรมี บทความนี้เจาะลึกรายละเอียดการสร้างกรอบการทดสอบจากมุมมองทางเทคนิค โดยมีรายละเอียดเกี่ยวกับสิ่งที่ควรรวมไว้ในการทดสอบแต่ละครั้งและสิ่งที่ควรหลีกเลี่ยง และที่สำคัญที่สุด คุณจะได้เรียนรู้คำตอบสำหรับคำถามเก่าเกี่ยวกับ "สิ่งที่ควรทดสอบ" หรือ "สิ่งที่ไม่ควรทดสอบ"

สิ่งที่จะทดสอบหรือไม่ทดสอบ

หลักเกณฑ์และรูปแบบทั่วไป

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

ทำให้เรียบง่าย

เมื่อพูดถึงข้อสอบ สิ่งสำคัญที่สุดอย่างหนึ่งที่ควรคำนึงถึงคือการเขียนให้ง่าย ควรคำนึงถึงความจุของสมอง โค้ดเวอร์ชันที่ใช้งานจริงหลักใช้พื้นที่จำนวนมาก จึงเหลือพื้นที่น้อยสำหรับความซับซ้อนเพิ่มเติม โดยเฉพาะอย่างยิ่งสําหรับการทดสอบ

หากมีช่องว่างน้อย คุณอาจรู้สึกผ่อนคลายระหว่างการทดสอบได้มากขึ้น คุณจึงควรให้ความสำคัญกับความเรียบง่ายในการทดสอบ อันที่จริงแล้ว แนวทางปฏิบัติที่ดีที่สุดในการทดสอบ JavaScript ของ Yoni Goldberg เน้นถึงความสำคัญของกฎทอง เนื่องจากการทดสอบควรมีลักษณะเหมือนผู้ช่วย ไม่ใช่สูตรทางคณิตศาสตร์ที่ซับซ้อน กล่าวคือ คุณควรเห็นจุดประสงค์ของการทดสอบได้อย่างรวดเร็ว

อย่าทำให้การทดสอบซับซ้อน นักเรียนไม่ควรรู้สึกเช่นนี้

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

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

ทดสอบว่าความคุ้มค่า

การออกแบบการทดสอบแบบ Flat Test ยังช่วยให้คุณมีสมาธิจดจ่อและช่วยให้ทำการทดสอบได้อย่างมีความหมาย อย่าลืมว่าคุณไม่ได้ต้องการสร้างการทดสอบเพื่อการครอบคลุมเท่านั้น แต่ควรมีจุดประสงค์อยู่เสมอ

อย่าทดสอบทุกอย่าง

ไม่ต้องทดสอบรายละเอียดการใช้งาน

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

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

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

เช่น การเลือกตัวเลือกที่มีแนวโน้มที่จะเปลี่ยนแปลงน้อยจะทำให้การทดสอบมีความน่าเชื่อถือมากขึ้น เช่น แอตทริบิวต์ข้อมูล แทนที่จะเป็นตัวเลือก CSS ดูรายละเอียดเพิ่มเติมได้ที่ Kent C. บทความของ Dodds เกี่ยวกับหัวข้อนี้ หรือโปรดติดตามต่อไป เราจะอ่านบทความนี้ในภายหลัง

ล้อเลียน: อย่ายอมเสียการควบคุม

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

การใช้การจำลองในการทดสอบของคุณจะช่วยเพิ่มความสามารถในการคาดการณ์ การแยกความกังวล และประสิทธิภาพ และหากคุณต้องการทำการทดสอบที่ต้องมีมนุษย์เข้าไปเกี่ยวข้อง (เช่น การยืนยันหนังสือเดินทาง) คุณจะต้องปกปิดการตรวจสอบโดยใช้การจำลองสถานการณ์ ด้วยเหตุผลทั้งหมดนี้ การจำลองจึงเป็นเครื่องมือที่มีประโยชน์ซึ่งควรพิจารณา

ในขณะเดียวกัน การล้อเลียนอาจส่งผลต่อความถูกต้องแม่นยำของการทดสอบเนื่องจากเป็นการจำลอง ไม่ใช่ประสบการณ์ของผู้ใช้จริง คุณจึงต้องใช้ความระมัดระวังเมื่อใช้ตัวอย่างและต้นขั้ว

คุณควรจำลองการทดสอบตั้งแต่ต้นจนจบหรือไม่

โดยทั่วไปแล้วจะไม่ใช่ แต่การล้อเลียนอาจช่วยชีวิตคุณได้ในบางครั้ง ดังนั้นอย่าตัดกันออกโดยสิ้นเชิง

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

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

ข้อมูลเฉพาะเกี่ยวกับการทดสอบ: สิ่งที่ควรและไม่ควรทำ

โดยรวมแล้ว การทดสอบประกอบด้วยอะไรบ้าง การทดสอบประเภทต่างๆ นั้นแตกต่างกันไหม มาดูรายละเอียดเกี่ยวกับแง่มุมเฉพาะบางอย่างที่ปรับให้เหมาะกับประเภทการทดสอบหลักๆ กัน

อะไรเป็นของการทดสอบ 1 หน่วยที่ดี

การทดสอบ 1 หน่วยที่ดีและมีประสิทธิภาพควรมีลักษณะดังนี้

  • มุ่งเน้นไปที่ด้านที่เฉพาะเจาะจง
  • ดำเนินงานได้โดยอิสระ
  • ครอบคลุมสถานการณ์ขนาดเล็ก
  • ใช้ชื่อที่สื่อความหมาย
  • ใช้รูปแบบ AAA หากมี
  • รับประกันความครอบคลุมของการทดสอบที่ครอบคลุม
ทำ ✅ สิ่งที่ไม่ควรทำ ❌
ทำการทดสอบให้น้อยที่สุดเท่าที่จะเป็นไปได้ ทดสอบ 1 สิ่งต่อกรอบการทดสอบ เขียนการทดสอบผ่านหน่วยขนาดใหญ่
แยกการทดสอบไว้ต่างหากเสมอ และลอกเลียนสิ่งที่คุณต้องการซึ่งอยู่นอกหน่วยของคุณ รวมองค์ประกอบหรือบริการอื่นๆ
ทำให้การทดสอบเป็นอิสระจากกัน อาศัยการทดสอบก่อนหน้าหรือแชร์ข้อมูลการทดสอบ
ครอบคลุมสถานการณ์และเส้นทางต่างๆ จำกัดตัวเองให้อยู่ในเส้นทางแห่งความสุขหรือการทดสอบเชิงลบ
ใช้ชื่อการทดสอบที่สื่อความหมายเพื่อให้ดูได้ทันทีว่าการทดสอบของคุณเกี่ยวกับอะไร ทดสอบตามชื่อฟังก์ชันเท่านั้น ไม่ได้อธิบายผลลัพธ์อย่าง testBuildFoo() หรือ testGetId()
พยายามทำให้โค้ดมีความครอบคลุมที่ดีหรือขอบเขตการทดสอบที่กว้างขึ้น โดยเฉพาะในขั้นตอนนี้ ทดสอบจากทุกคลาสไปจนถึงระดับฐานข้อมูล (I/O)

อะไรเป็นของการทดสอบการผสานรวมที่ดี

การทดสอบการรวมระบบที่เหมาะสมจะใช้เกณฑ์บางอย่างร่วมกับการทดสอบ 1 หน่วยด้วยเช่นกัน อย่างไรก็ตาม มีประเด็นเพิ่มเติม 2 ประการที่คุณต้องพิจารณา การทดสอบการผสานรวมที่ดีควรมีลักษณะดังนี้

  • จำลองการโต้ตอบระหว่างคอมโพเนนต์
  • เล่าเหตุการณ์ในชีวิตจริงและใช้มุกตลกหรือต้นขั้ว
  • พิจารณาประสิทธิภาพ
ทำ ✅ สิ่งที่ไม่ควรทำ ❌
ทดสอบจุดผสานรวม: ตรวจสอบว่าแต่ละหน่วยทำงานร่วมกันอย่างลงตัวเมื่อผสานรวมเข้าด้วยกัน ทดสอบแต่ละหน่วยโดยแยกกัน ซึ่งก็คือรหัสการทดสอบ 1 หน่วย
ทดสอบสถานการณ์จริง: ใช้ข้อมูลทดสอบที่ได้จากข้อมูลจริง ใช้ข้อมูลการทดสอบที่สร้างขึ้นโดยอัตโนมัติซ้ำๆ หรือข้อมูลอื่นๆ ที่ไม่ได้แสดงถึงกรณีการใช้งานจริง
ใช้การจำลองและต้นขั้วสำหรับทรัพยากร Dependency ภายนอกเพื่อรักษาการควบคุมการทดสอบที่สมบูรณ์ไว้ สร้างทรัพยากร Dependency กับบริการของบุคคลที่สาม เช่น คำขอของเครือข่ายไปยังบริการภายนอก
ใช้กิจวัตรการทำความสะอาดก่อนและหลังการทดสอบแต่ละครั้ง ลืมใช้มาตรการทำความสะอาดภายในการทดสอบ มิฉะนั้นอาจทำให้ทดสอบไม่สำเร็จหรือผลบวกลวง เนื่องจากไม่มีการแยกการทดสอบที่เหมาะสม

อะไรเป็นของการทดสอบที่ดีตั้งแต่ต้นจนจบ

การทดสอบแบบรอบด้านที่ครอบคลุมควรมีลักษณะดังนี้

  • จำลองการโต้ตอบของผู้ใช้
  • ครอบคลุมสถานการณ์ที่สำคัญ
  • กระจายหลายเลเยอร์
  • จัดการการดำเนินการแบบอะซิงโครนัส
  • ยืนยันผลลัพธ์
  • คำนึงถึงประสิทธิภาพ
ทำ ✅ สิ่งที่ไม่ควรทำ ❌
ใช้แป้นพิมพ์ลัดที่ขับเคลื่อนด้วย API ดูข้อมูลเพิ่มเติม ใช้การโต้ตอบ UI สำหรับทุกขั้นตอน รวมถึงฮุก beforeEach
ใช้กิจวัตรการล้างพื้นที่เก็บข้อมูลก่อนการทดสอบแต่ละครั้ง ให้ความสำคัญกับการแยกการทดสอบมากกว่าการทดสอบหน่วยและการทดสอบการผสานรวมเนื่องจากมีความเสี่ยงสูงที่จะเกิดผลข้างเคียงจากตรงนี้ ลืมทำความสะอาดหลังการทดสอบแต่ละครั้ง หากไม่ล้างสถานะ ข้อมูล หรือผลข้างเคียงที่เหลือออก การเปลี่ยนแปลงเหล่านี้จะส่งผลต่อการทดสอบอื่นๆ ที่ดำเนินการในภายหลัง
พิจารณาการทดสอบตั้งแต่ต้นจนจบว่าเป็นการทดสอบระบบ ซึ่งหมายความว่าคุณต้องทดสอบกลุ่มแอปพลิเคชันทั้งหมด ทดสอบแต่ละหน่วยโดยแยกกัน ซึ่งก็คือรหัสการทดสอบ 1 หน่วย
ใช้การล้อเลียนให้น้อยที่สุดหรือไม่มีเลยภายในการทดสอบ โปรดพิจารณาอย่างรอบคอบหากต้องการจำลองทรัพยากร Dependency ภายนอก พึ่งพาการจำลองจำนวนมาก
ตัวอย่างเช่น พิจารณาประสิทธิภาพและภาระงานโดยอย่าทดสอบสถานการณ์ขนาดใหญ่ในการทดสอบเดียวกันมากเกินไป ครอบคลุมเวิร์กโฟลว์ขนาดใหญ่โดยไม่ต้องใช้ทางลัด