การทดสอบแต่ละหน่วยควรจะสามารถทำงานโดยอิสระจากการทดสอบอื่น ๆ


24

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

ตอนนี้วิธีที่สองนี้อาจมีอินพุตฮาร์ดโค้ดเช่นเดียวกับแรกหรืออาจสันนิษฐานได้ว่าการทดสอบทั้งสองนั้นจะทำงานตามลำดับและสามารถเลือกได้ว่าการทดสอบครั้งแรกจะถูกเก็บไว้ที่ใดจากการทดสอบครั้งแรก

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

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

ตัวเลือกไหนดีกว่าที่นี่? มีทางเลือกบางอย่างเช่นมีการทดสอบเดี่ยวสำหรับแต่ละวิธีแยกด้วย hardcoding แล้วทดสอบที่ใหญ่กว่าที่มีทั้งสองวิธีในหนึ่งเดียว?


2
ฉันหวังว่าฉันจะสามารถสุ่มลำดับของการทดสอบหน่วยทุกครั้งที่พวกเขาทำงานได้อย่างง่ายดาย ตอนนี้พวกเขาทำงานในบางที่ไม่รู้จักแม้ว่าจะค่อนข้างคงที่
งาน

คำตอบ:


11

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

หากวิธีการของคุณเป็นอิสระอย่างแท้จริงสิ่งนี้ไม่สำคัญ วิธีที่สองของคุณควร:

a) ทำงานอย่างถูกต้องเมื่อแสดงด้วยข้อมูลที่ถูกต้อง

b) ล้มเหลวอย่างสมเหตุสมผลและสม่ำเสมอเมื่อนำเสนอด้วยข้อมูลที่ไม่ถูกต้อง

วิธีแรกของคุณควรทำเช่นเดียวกัน ดังนั้นตราบใดที่คุณจัดการกับข้อผิดพลาดพวกเขาจะทำงานร่วมกันอย่างถูกต้อง

หากคุณต้องการทดสอบว่าวิธีการทำงานร่วมกันอย่างถูกต้องนั้นคือการทดสอบการรวมไม่ทดสอบหน่วย


27

หากการทดสอบไม่สามารถทำงานได้อย่างอิสระพวกเขาไม่ใช่การทดสอบหน่วย

การทดสอบหน่วยไม่ควรพึ่งพาสถานะภายนอกใด ๆ เช่นเนื้อหาของตารางฐานข้อมูล ควรทดสอบโค้ดอย่างเดียวโดยแยกหน่วย

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


@Steve ดังนั้นในตัวอย่างนี้คุณจะพูดว่า: การทดสอบหนึ่งสำหรับวิธีที่ 1 ทดสอบหนึ่งสำหรับวิธีที่ 2 และทดสอบหนึ่งที่รัน 1 และ 2 ในการทดสอบเดียวกันหรือไม่
Morgan Herlocker

2
ใช่. สองรายการแรกคือการทดสอบหน่วยเสียงที่สามคล้ายกับการทดสอบการรวม
Steve

หากคุณมีโมดูลลูกค้าและโมดูลการสั่งซื้อและไม่สามารถสร้างคำสั่งซื้อโดยไม่เกี่ยวข้องกับลูกค้า คุณจะทดสอบความเป็นอิสระจากโมดูลลูกค้าได้อย่างไร: สร้างบันทึกลูกค้าในฐานข้อมูลด้วย sql (แทรกลงในลูกค้า) หรือใช้ Customer.createCustomer () และ IMHO ใช้อันดับที่สองนั้นดีกว่าเนื่องจากคุณไม่จำเป็นต้องใช้ตรรกะในการทดสอบ แต่จะใช้งานได้ก็ต่อเมื่อการทดสอบของคุณในการสร้างลูกค้าผ่าน
Dainius

@Dainius ในสถานการณ์การทดสอบหน่วยโดยทั่วไปคุณจะใช้วัตถุจำลองดังนั้นคุณจะส่งลูกค้าจำลองไปยังโมดูลการสั่งซื้อของคุณ คุณมีสิทธิ์ที่จะไม่ใช้ sql ในกรณีนี้
Steve

ดูเหมือนว่าในสถานการณ์ใด ๆ ที่เมธอด B ขึ้นอยู่กับเมธอด A มักจะมีเมธอด C ที่เรียก A แล้วเรียก B เนื่องจากเป็นกรณีนี้คุณสามารถทดสอบ A, B และ C ได้อย่างอิสระ
Morgan Herlocker

9

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

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


1
+1 Raskolnikov ฉันไม่ได้พิจารณาข้อเท็จจริงที่ว่านี่จะเป็นช่วงเวลาที่ยิ่งใหญ่ในภายหลังเมื่อฉัน "ทำการทดสอบทั้งหมด" ในภายหลังในบรรทัด
Morgan Herlocker

3

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.