การทดสอบหน่วยยืนยันเดียวไม่ทำลายหลักการ DRY หรือไม่


12

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

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

และมีกฎที่ดีหรือไม่ที่จะต้องปฏิบัติตามเพื่อหาสมดุลที่ดีเช่นเดียวกับการทดสอบหนึ่งวิธีต่อหนึ่งวิธี *

* ฉันรู้ว่าอาจไม่ได้มีขนาดเดียวที่เหมาะกับการแก้ปัญหาทั้งหมดนี้ แต่มีวิธีแนะนำให้ใช้วิธีนี้หรือไม่


5
คุณสามารถแยกรหัสที่คุณคัดลอกเป็นวิธีได้
Ismail Badawi

@IsmailBadawi ที่ดูเหมือนความคิดที่ดี ฉันจะสมมติวิธีการเหล่านี้ควรกลับตัวอย่างของวัตถุชั้นเรียนที่ฉันกำลังทดสอบ
Korey Hinton

1
คุณกำลังสร้างบางสิ่งในสถานะที่กำหนดที่จะทดสอบหรือไม่ นั่นฟังดูเป็นประจำ
Dave Hillier

@ DaveHillier ใช่ฉันได้เรียนรู้คำศัพท์ใหม่วันนี้ ขอบคุณ :)
Korey Hinton

ขึ้นอยู่กับว่าคุณตีความ 1 assert ต่อการทดสอบอย่างไรถ้าคุณหมายถึง Assert * หนึ่ง call แล้วใช่ถ้าคุณต้องการให้แน่ใจว่าค่าคงที่ยังคงอยู่ การทดสอบทีในยืนยันเดียว (หรือถ้าคุณทำแล้วมันจะไม่เป็นที่ชัดเจนว่าทำไมมันล้มเหลว)
วงล้อประหลาด

คำตอบ:


14

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

public void AddNewCustomer_CustomerExists_ThrowsException()

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

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

ใน TDD ไม่มีการทดสอบคือ YAGNI เนื่องจากคุณเขียนการทดสอบตามสิ่งที่คุณต้องการให้รหัสของคุณเท่านั้น หากคุณไม่ต้องการคุณจะไม่เขียนบททดสอบ


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

ในประเด็นสุดท้ายของคุณฉันแน่ใจว่าฉันสามารถเขียนการทดสอบสำหรับการทำงานฉันชอบรหัสที่จะมีมากกว่าฟังก์ชั่นที่จำเป็น
joelb

5

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

ไม่ แต่มันส่งเสริมการละเมิด

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

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

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

ฉันคิดว่ามันเป็นการเปลี่ยนแปลงในหลักการความรับผิดชอบเดี่ยว: ควรมีเพียงสิ่งเดียวเท่านั้นที่สามารถทำให้การทดสอบล้มเหลวและในโลกอุดมคติที่การเปลี่ยนแปลงควรทำลายการทดสอบเพียงครั้งเดียว

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


1
สำหรับการทดสอบสิ่งสำคัญคือการทำให้ชื้นมากกว่า DRY (วลีเชิงพรรณนาและความหมาย)
Jörg W Mittag

2

ไม่ดูเหมือนจะเป็นแบบที่คุณทำ หากคุณไม่พบข้อมูลอ้างอิงที่โดดเด่นที่พวกเขาอ้างว่านี่เป็นแนวทางปฏิบัติที่ดี

ใช้ฟิกซ์เจอร์ทดสอบ (แม้ว่าใน XUnit คำศัพท์ของชุดการทดสอบการติดตั้งและการฉีกขาดคือฟิกซ์เจอร์ทดสอบ) นั่นคือการตั้งค่าบางอย่างหรือตัวอย่างที่ใช้กับการทดสอบทั้งหมดของคุณ

ใช้วิธีการต่าง ๆ เช่นปกติโครงสร้างรหัสของคุณ เมื่อทำการทดสอบการเปลี่ยนสภาพใหม่ TDD Red-Green-Refactor ปกติไม่ได้ใช้ให้ใช้ "การเปลี่ยนสีในสีแดง" แทน นั่นคือ,

  1. จงใจทำลายการทดสอบของคุณ
  2. ทำ refactoring ของคุณ
  3. แก้ไขการทดสอบของคุณ

วิธีนี้คุณจะรู้ว่าการทดสอบยังให้ผลบวกและลบ

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

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