พิจารณาว่าคุณต้องการทดสอบอะไรและอะไรที่สามารถตัดออกได้
บทความก่อนหน้านี้พูดถึงข้อมูลเบื้องต้นเกี่ยวกับกรอบการทดสอบและสิ่งที่ควรมี บทความนี้เจาะลึกรายละเอียดการสร้างกรอบการทดสอบจากมุมมองทางเทคนิค โดยมีรายละเอียดเกี่ยวกับสิ่งที่ควรรวมไว้ในการทดสอบแต่ละครั้งและสิ่งที่ควรหลีกเลี่ยง และที่สำคัญที่สุด คุณจะได้เรียนรู้คำตอบสำหรับคำถามเก่าเกี่ยวกับ "สิ่งที่ควรทดสอบ" หรือ "สิ่งที่ไม่ควรทดสอบ"
หลักเกณฑ์และรูปแบบทั่วไป
โปรดสังเกตว่ารูปแบบและประเด็นเฉพาะนั้นมีความสำคัญมาก ไม่ว่าคุณจะทำการทดสอบหน่วย การผสานรวม หรือการทดสอบตั้งแต่ต้นจนจบ หลักการเหล่านี้สามารถและควรนำไปใช้กับการทดสอบทั้ง 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 ภายนอก | พึ่งพาการจำลองจำนวนมาก |
ตัวอย่างเช่น พิจารณาประสิทธิภาพและภาระงานโดยอย่าทดสอบสถานการณ์ขนาดใหญ่ในการทดสอบเดียวกันมากเกินไป | ครอบคลุมเวิร์กโฟลว์ขนาดใหญ่โดยไม่ต้องใช้ทางลัด |