ความแตกต่างระหว่างการทดสอบหน่วยและการพัฒนาแบบทดสอบขับเคลื่อน


64

จากการอ่านคำอธิบายฉันเข้าใจว่าในการทดสอบ TDD เสร็จแล้วก่อนที่จะเขียนฟังก์ชั่นและในการทดสอบหน่วยมันทำหลังจากนั้น

นี่เป็นความแตกต่างหลักหรือไม่สามารถเปรียบเทียบสองคำนี้ได้ บางทีการทดสอบหน่วยเป็นส่วนหนึ่งของ TDD

คำตอบ:


104

หน่วยทดสอบหมายถึงสิ่งที่คุณกำลังทดสอบ, TDDไปเมื่อคุณกำลังทดสอบ

ทั้งสองเป็นมุมฉาก

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

คุณสามารถเขียนการทดสอบหน่วยก่อนที่จะเขียนรหัสของคุณหลังจากที่คุณเขียนรหัสของคุณหรือในขณะที่คุณเขียนรหัสของคุณ

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

ส่วนที่สำคัญที่สุดของ TDD เป็นกลางD คุณปล่อยให้การทดสอบผลักดันคุณ การทดสอบจะบอกคุณว่าต้องทำอย่างไรจะทำอย่างไรต่อไปเมื่อคุณทำเสร็จแล้ว พวกเขาบอกคุณว่า API จะเป็นอย่างไรการออกแบบคืออะไร (นี่เป็นสิ่งสำคัญ: TDD ไม่ได้เกี่ยวกับการเขียนการทดสอบก่อนมีหลายโครงการที่เขียนการทดสอบก่อน แต่ไม่ฝึก TDD การทดสอบการเขียนครั้งแรกนั้นเป็นข้อกำหนดเบื้องต้นสำหรับความสามารถในการปล่อยให้การทดสอบพัฒนาขึ้น)


1
คำตอบที่ดี จะเพิ่ม ... TDD คือเมื่อคุณให้การทดสอบเพื่อผลักดันคุณและคุณสมบัติที่จะดึงความพยายามในการพัฒนาของคุณ ...
Martin

พวกเขาไม่ได้ตั้งฉากแม้ว่า คุณไม่สามารถมี TDD ได้หากไม่มีการทดสอบหน่วย
JacquesB

1
@JacquesB ทำไม การทดสอบของเราไม่ใช่สิ่งที่คุณเรียกการทดสอบหน่วยโดยคำจำกัดความใด ๆ พวกเขาอาศัยโครงสร้างพื้นฐานและส่วนประกอบอื่น ๆ มากเกินไป แต่เรายังมีความสามารถในการสังเกตที่เพียงพอซึ่งอย่างน้อยพวกเราบางคนกำลังทำ TDD
AProgrammer

3
@AndrewWillems: TDD หมายความว่าการทดสอบการขับรถการพัฒนา คุณไม่ได้ตัดสินใจว่าการออกแบบหน้าตาเป็นอย่างไรการทดสอบบอกคุณ คุณไม่ได้ตัดสินใจว่าจะทำงานต่อไปอย่างไรการทดสอบจะบอกคุณ คุณไม่ตัดสินใจเมื่อเสร็จการทดสอบจะบอกคุณ เป็นไปได้อย่างสมบูรณ์แบบที่จะเขียนการทดสอบก่อนจากนั้นเพิกเฉยต่อสิ่งที่พวกเขาบอกคุณ ตัวอย่างเช่นคุณสามารถเขียนการทดสอบก่อนได้ แต่จากนั้นให้เขียนโค้ดต่อไปแม้หลังจากการทดสอบทั้งหมดเป็นสีเขียว ในคำอื่น ๆ : คุณเขียนการทดสอบก่อน แต่คุณปฏิบัติต่อพวกเขาเช่นเดียวกับการทดสอบและจะไม่ปล่อยให้พวกเขาผลักดันการพัฒนา
Jörg W Mittag

1
@ JörgWMittagคุณอาจจะมองอย่างตรงไปตรงมา แต่คุณก็รู้ว่า TDD ไม่ใช่ขาวดำ การใช้ TDD อย่างมีสติจะไม่ยอมให้การทดสอบขับเคลื่อนการพัฒนาอย่างสมบูรณ์และการทดสอบนั้นไม่ได้ตัดสินว่าการออกแบบนั้นมีลักษณะเป็นอย่างไร แล้วการรีฟอร์เรชั่นล่ะ? ซึ่งเป็นสิ่งสำคัญมากของ TDD ในโลกแห่งความเป็นจริงไม่มีสิ่งใดที่ 'ละเว้นทุกสิ่งที่การทดสอบกำลังบอกคุณ' ตามคำนิยามถ้าคุณเขียนการทดสอบก่อนคุณใช้ 'บางรูปแบบของ TDD'
NickL

21

การทดสอบหน่วยเป็นส่วนประกอบของการทดสอบพัฒนา

คุณสามารถทำการทดสอบหน่วยโดยไม่ต้องทำการพัฒนาที่ขับเคลื่อนการทดสอบ อย่างไรก็ตามคุณไม่สามารถทำการพัฒนาที่ขับเคลื่อนการทดสอบได้โดยไม่ต้องใช้การทดสอบหน่วย

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

แนวทางการพัฒนาแบบทดสอบคือการเขียนบททดสอบก่อนเขียนโค้ด

ข้อได้เปรียบที่น่าสนใจที่สุดของ TDD (IMHO) เปรียบเทียบกับการทดสอบหน่วยอย่างง่าย:

  • รหัสคือการทดสอบรหัสล่วงหน้าอย่างสมบูรณ์ เป็นการทดสอบที่ไม่เจ็บปวด
  • มันบังคับให้คุณออกแบบคลาสของคุณอย่างถูกต้อง
  • นอกจากนี้ยังบังคับให้คุณให้มันง่ายโง่
  • วัฏจักรของ Red-Green-Refactor คือนักฆ่าการผัดวันประกันพรุ่งอย่างแน่นอน!

คุณพลาด "หน่วย" โดยมีจุดประสงค์ในกฎหมายหรือไม่: "อย่างไรก็ตามคุณไม่สามารถทำการพัฒนาแบบทดสอบได้หากไม่ได้ใช้การทดสอบ" ?
ratkok

@ratkok: ไม่นั่นไม่ได้ตั้งใจ ขอผมแก้ไขหน่อย

ฉันชอบคำจำกัดความที่ดีที่สุด มันรวบรวมคำศัพท์ได้ดีกว่าคำตอบอื่น ๆ
Tek

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

13

การทดสอบ TDD และหน่วยเป็นคำศัพท์เฉพาะสองคำที่มักถูกนำไปใช้ในทางที่ผิด

TDD กำลังเขียนการทดสอบที่จะล้มเหลวจากนั้นจึงเขียนจำนวนรหัสขั้นต่ำที่จำเป็นในการเรียกใช้จากนั้นทำการปรับโครงสร้างรหัสใหม่เพื่อทำให้สะอาด สิ่งนี้ทำในรอบ, ล้มเหลว -> pass -> refactor, เพิ่มการทดสอบใหม่สำหรับข้อกำหนดที่ทราบสำหรับแต่ละรหัส เมื่อไม่นานมานี้ TDD ได้กลายเป็นเรื่องที่เฉพาะเจาะจงมากขึ้นเกี่ยวกับการเขียนการทดสอบหน่วยในรอบนั้นเพื่อแยกความแตกต่างจาก ATDD (เซตย่อยของ BDD) ซึ่งกำลังเขียนการทดสอบการยอมรับในรอบเดียวกัน

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


1
การทดสอบ JUnit สำหรับ JUnit นั้นเป็นตัวอย่างที่ดี: ส่วนสำคัญของการทดสอบเหล่านี้คือการทดสอบการใช้งานและการทดสอบการยอมรับไม่ใช่การทดสอบหน่วยแม้ว่าจะเขียนด้วย JUnit ก็ตาม นอกจากนี้ผู้สร้าง JUnit ยังเป็นผู้สร้าง TDD และ JUnit ได้รับการพัฒนาโดยใช้ TDD โดยใช้การทดสอบการใช้งานและการทดสอบการยอมรับจำนวนมาก การทดสอบการยอมรับเป็นส่วนหนึ่งของ TDD
Jörg W Mittag

6

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


3

TDD เป็นวิธีการเชิงปรัชญาในการเขียนรหัส: เขียนการทดสอบก่อน การทดสอบที่คุณเขียนคือการทดสอบหน่วย


1

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


1

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

(ตัวแปร TDD บางตัวมองว่า 'หน่วย' เป็นขั้นตอนส่วนเพิ่มเล็กที่สุดไปยังฟังก์ชันที่ต้องการ ... )


พวกเขาควร แต่ในประสบการณ์ของฉันในความเป็นจริงพวกเขาทำไม่ได้ บริษัท / กลุ่มบอกว่าพวกเขาทำ TDD เมื่อสิ่งที่พวกเขาทำคือบังคับให้โปรแกรมเมอร์ทำการทดสอบครั้งแรกด้วยการทดสอบ jUnit จากนั้นใช้ข้อเท็จจริงที่ว่าทุกอย่างได้รับการทดสอบแล้วในระหว่างการพัฒนาเพื่อทำแบบทดสอบ (หรือลดลงอย่างมาก)
jwenting

1
@ jwenting ไม่ได้ตำหนิวิธีการสำหรับข้อบกพร่องของผู้ที่อ้างว่าได้ฝึกฝน เครื่องมือใด ๆ ที่สามารถนำไปใช้ในทางที่ผิด
Steven A. Lowe

1
ฉันไม่ได้ แต่คุณต้องตระหนักว่ามันมีความแตกต่างอย่างมากระหว่าง TDD กับทฤษฎีและสิ่งที่เป็นจริง และในขณะที่คนส่วนใหญ่ (รวม OP) อาจจะเห็นความจริงเท่านั้นความแตกต่างควรชี้ไปที่พวกเขา
jwenting

พิจารณาว่า TDD เป็นเรื่องของการออกแบบ - ทำไมถึงต้องมีการทดสอบการยอมรับ มันจะ "ขับ" การออกแบบได้อย่างไร?
Vitalii Isaenko

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