คนที่ทำ TDD จะจัดการกับการสูญเสียงานเมื่อทำ refactoring สำคัญได้อย่างไร


37

ในขณะที่ฉันพยายามเรียนรู้การเขียนการทดสอบหน่วยสำหรับรหัสของฉัน

ตอนแรกฉันเริ่มต้นทำ TDD จริงซึ่งฉันจะไม่เขียนโค้ดใด ๆ จนกว่าฉันจะเขียนการทดสอบที่ล้มเหลวก่อน

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

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

ฉันอดไม่ได้ที่จะคิดว่าฉันได้ลองใช้เวลา 3 หรือ 4 วันในการเขียนแบบทดสอบเมื่อฉันสามารถใส่รหัสเข้าด้วยกันเพื่อพิสูจน์แนวคิดแล้วเขียนการทดสอบหลังจากนั้นเมื่อฉันมีความสุขกับวิธีการของฉัน

คนที่ฝึกฝน TDD รับมือกับสถานการณ์เช่นนี้ได้อย่างไร? มีกรณีสำหรับการดัดกฎในบางกรณีหรือคุณมักจะเขียนแบบทดสอบก่อนเสมอแม้ว่ารหัสนั้นอาจไร้ประโยชน์หรือไม่?


6
ความสมบูรณ์แบบนั้นเกิดขึ้นได้ไม่ใช่เมื่อไม่มีอะไรจะเพิ่มเติมอีกต่อไป แต่เมื่อไม่มีอะไรเหลือให้เอาไป - Antoine de Saint-Exupery
mouviciel

12
เป็นไปได้อย่างไรที่การทดสอบทั้งหมดของคุณผิด โปรดอธิบายว่าการเปลี่ยนแปลงในการใช้งานจะทำให้การทดสอบแต่ละครั้งของคุณไม่ถูกต้อง
S.Lott

6
@ S.Lott: การทดสอบไม่ผิดพวกเขาไม่เกี่ยวข้องกันอีกต่อไป สมมติว่าคุณกำลังแก้ปัญหาโดยใช้หมายเลขเฉพาะดังนั้นคุณเขียนชั้นเรียนเพื่อสร้างหมายเลขเฉพาะและเขียนแบบทดสอบสำหรับชั้นเรียนนั้นเพื่อให้แน่ใจว่ามันทำงานได้จริง ในตอนนี้คุณจะพบวิธีแก้ปัญหาที่แตกต่างอย่างสิ้นเชิงกับปัญหาของคุณซึ่งไม่เกี่ยวข้องกับช่วงเวลาในทางใดทางหนึ่ง ชั้นเรียนนั้นและการทดสอบตอนนี้ซ้ำซ้อน นี่คือสถานการณ์ของฉันเฉพาะกับ 10 ของชั้นเรียนไม่ได้เป็นเพียงหนึ่ง
GazTheDestroyer

5
@GazTheDestroyer มันดูเหมือนว่าฉันที่แยกความแตกต่างระหว่างรหัสทดสอบและรหัสการทำงานเป็นความผิดพลาด - มันเป็นส่วนหนึ่งของกระบวนการพัฒนาเดียวกันทั้งหมด มีความเป็นธรรมที่จะต้องทราบว่า TDD มีค่าใช้จ่ายที่มักจะได้รับการกู้คืนต่อไปในกระบวนการพัฒนาและดูเหมือนว่าค่าใช้จ่ายที่ไม่ได้รับคุณในกรณีนี้ แต่การทดสอบเท่าไหร่บอกให้คุณเข้าใจถึงความล้มเหลวของสถาปัตยกรรม? เป็นสิ่งสำคัญที่จะต้องทราบว่าคุณได้รับอนุญาต (ไม่สนับสนุน ) เพื่อตัดการทดสอบของคุณเมื่อเวลาผ่านไป ... แม้ว่ามันอาจจะค่อนข้างรุนแรง (-:
Murph

10
ฉันจะมีความหมายเชิงความหมายและเห็นด้วยกับ @ S.Lott ที่นี่; สิ่งที่คุณทำไม่ได้เป็นการปรับโครงสร้างใหม่หากมันส่งผลให้มีการทิ้งคลาสและการทดสอบสำหรับพวกเขามากมาย ว่าre-architecting การปรับโครงสร้างใหม่โดยเฉพาะอย่างยิ่งในแง่ของ TDD หมายความว่าการทดสอบเป็นสีเขียวคุณเปลี่ยนรหัสภายในบางส่วนทำการทดสอบซ้ำอีกครั้งและพวกเขายังคงเป็นสีเขียว
Eric King เมื่อ

คำตอบ:


33

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

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

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


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

3
"ฉันทำการทดสอบการเขียนเหมือนที่เคยทำมาเพราะนั่นคือสิ่งที่วรรณกรรม TDD เน้นมาก" คุณอาจต้องอัปเดตคำถามกับแหล่งที่มาของความคิดของคุณว่าการทดสอบทั้งหมดจะต้องเขียนก่อนรหัสใด ๆ
S.Lott

1
ฉันไม่มีความคิดเช่นนั้นและฉันไม่แน่ใจว่าคุณได้รับสิ่งนั้นจากความคิดเห็นได้อย่างไร
GazTheDestroyer

1
ฉันกำลังจะเขียนคำตอบ แต่คุณแทนที่ upvote แทน ใช่ล้านครั้งใช่: ถ้าคุณไม่ได้รู้ว่าสิ่งที่มีลักษณะสถาปัตยกรรมของคุณชอบยังเขียนต้นแบบใบปลิวครั้งแรกและไม่ต้องรำคาญกับการเขียนการทดสอบหน่วยในระหว่างการสร้างต้นแบบ
Robert Harvey

1
@WarrenP แน่นอนว่ามีคนที่คิดว่า TDD เป็นหนทางเดียว (สิ่งใดก็ตามที่สามารถกลายเป็นศาสนาได้หากคุณพยายามอย่างหนักพอ ;-) ฉันชอบที่จะเน้นการปฏิบัติ สำหรับฉัน TDD เป็นเครื่องมือหนึ่งในกล่องเครื่องมือของฉันและฉันใช้เฉพาะเมื่อมันช่วยได้แทนที่จะเป็นอุปสรรคต่อการแก้ปัญหา
PéterTörök

8

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


3
วิธีการของฉันไม่ใหญ่เลยพวกเขาก็ไม่เกี่ยวข้องเลยเพราะสถาปัตยกรรมใหม่ที่ไม่มีความคล้ายคลึงกับสถาปัตยกรรมเก่า ส่วนหนึ่งเป็นเพราะสถาปัตยกรรมใหม่นั้นง่ายกว่ามาก
GazTheDestroyer

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

1
@Kilian อีกครั้ง "สัญญาของ TDD คือทำให้คุณบรรลุเป้าหมายเดียวกันได้เร็วขึ้น" - คุณหมายถึงเป้าหมายอะไรที่นี่? ค่อนข้างชัดเจนว่าการเขียนการทดสอบหน่วยพร้อมกับรหัสการผลิตทำให้คุณช้าลงในตอนแรกเมื่อเทียบกับการปั่นโค้ด ฉันจะบอกว่า TDD จะจ่ายคืนในระยะยาวเท่านั้นเนื่องจากคุณภาพที่ดีขึ้นและค่าใช้จ่ายในการบำรุงรักษาลดลง
PéterTörök

@ PéterTörök - มีคนที่ยืนยันว่า TDD ไม่เคยมีค่าใช้จ่ายใด ๆ เพราะจะจ่ายให้ตัวเองตามเวลาที่คุณเขียนรหัส นั่นไม่ใช่กรณีของฉัน แต่ Killian ดูเหมือนจะเชื่อด้วยตัวเอง
psr

ถ้าคุณไม่เชื่อในความเป็นจริงถ้าคุณไม่เชื่อว่า TDD มีการจ่ายผลตอบแทนมากกว่าค่าใช้จ่ายก็ไม่มีประเด็นใดที่จะทำเช่นนั้นเลยใช่ไหม? ไม่เพียง แต่ในสถานการณ์ที่เฉพาะเจาะจงมากที่แก๊ซอธิบาย แต่ที่ทุกคน ฉันกลัวว่าตอนนี้ฉันจะผลักดันหัวข้อนี้อย่างสมบูรณ์นอกหัวข้อ :(
Kilian Foth

6

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

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

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


มันเป็นเพียงอุปกรณ์ต่อพ่วง แต่ PDE คืออะไร
CVn

1
@ MichaelKjörlingฉันเดาว่ามันเป็นสมการอนุพันธ์ย่อยบางส่วน
foraidt

2
Brooks ไม่เพิกถอนคำแถลงดังกล่าวในรุ่นที่ 2 ของเขาหรือไม่
Simon

คุณหมายความว่าคุณยังคงมีการทดสอบที่แสดงว่า Runge-Kutta ไม่เหมาะ? การทดสอบเหล่านั้นมีลักษณะอย่างไร คุณหมายความว่าคุณบันทึกอัลกอริทึม Runge-Kutta ที่คุณเขียนไว้ก่อนที่จะค้นพบว่ามันไม่เหมาะสมและการทดสอบแบบ end-to-end ด้วย RK ในการผสมจะล้มเหลวหรือไม่
moteutsch

5

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

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


1
ฉันคิดว่าฉันอธิบายตัวเองไม่ค่อยดี ฉันเขียนข้อสอบซ้ำ ๆ นั่นคือวิธีที่ฉันลงเอยด้วยการทดสอบหลายร้อยครั้งสำหรับรหัสที่เกิดขึ้นซ้ำซ้อน
GazTheDestroyer

1
ข้างต้น - ฉันคิดว่ามันควรจะคิดว่าเป็น "การทดสอบและรหัส" มากกว่า "การทดสอบสำหรับรหัส"
Murph

1
+1: "คุณไม่ควรพยายามเขียนการทดสอบทั้งหมดในครั้งเดียว"
S.Lott

4

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

สิ่งที่ฉันได้เรียนรู้เปรียบเทียบโครงการ TDD ในชีวิตจริงที่ฉันทำงานด้วย (ไม่มากในความเป็นจริงเพียง 3 ครอบคลุม 2 ปีของการทำงาน) กับสิ่งที่ฉันได้เรียนรู้ในทางทฤษฎีคือการทดสอบอัตโนมัติ! = การทดสอบหน่วย แต่เพียงผู้เดียว)

กล่าวอีกนัยหนึ่ง T ใน TDD ไม่จำเป็นต้องมี U ด้วย ... มันเป็นแบบอัตโนมัติ แต่มีการทดสอบหน่วยน้อยกว่า (เช่นในชั้นเรียนการทดสอบและวิธีการ) น้อยกว่าการทดสอบการทำงานอัตโนมัติ: อยู่ในระดับเดียวกัน การทำงานที่ละเอียดเป็นสถาปัตยกรรมที่คุณกำลังทำงานในปัจจุบัน คุณเริ่มต้นในระดับสูงด้วยการทดสอบเพียงเล็กน้อยและมีเพียงภาพใหญ่ที่ใช้งานได้และในที่สุดคุณก็จะจบลงด้วย UT หลายพันรายการและคลาสทั้งหมดของคุณได้รับการกำหนดไว้อย่างดีในสถาปัตยกรรมที่สวยงาม ...

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

อาจเป็นเพียงวิธีส่วนตัวของฉันในการทำเช่นนี้ ฉันไม่มีประสบการณ์เพียงพอที่จะตัดสินใจตั้งแต่เริ่มต้นว่ารูปแบบหรือโครงสร้างใดที่โครงการของฉันจะมีดังนั้นฉันจะไม่เสียเวลาเขียน UT 100s ตั้งแต่ต้น ...

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


3
พูดได้ดี - เป็น TDD ไม่ใช่ UTDD
Steven A. Lowe

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

4
คนที่ฝึกฝน TDD รับมือกับสถานการณ์เช่นนี้ได้อย่างไร?
  1. โดยพิจารณาว่าเมื่อใดที่จะต้องสร้างต้นแบบเทียบกับเมื่อถึงรหัส
  2. โดยตระหนักว่าการทดสอบหน่วยนั้นไม่เหมือนกับ TDD
  3. โดยการเขียนการทดสอบ TDD เพื่อตรวจสอบคุณสมบัติ / เรื่องไม่ใช่หน่วยการทำงาน

Conflation ของการทดสอบหน่วยที่มีการพัฒนาที่ขับเคลื่อนด้วยการทดสอบนั้นเป็นที่มาของความปวดร้าวและความฉิบหายมากมาย ดังนั้นเรามาทบทวนอีกครั้ง:

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

โดยสรุป: การทดสอบหน่วยมีการมุ่งเน้นการใช้งาน TDD มีการมุ่งเน้นข้อกำหนด พวกเขาไม่เหมือนกัน


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

1
@ ian31: ตัวอย่างที่สมบูรณ์แบบของการทำ UT และ TDD จะต้องไม่เห็นด้วยและนำคุณไปยังแหล่งที่มาของวัสดุบางอย่างen.wikipedia.org/wiki/Test-driven_development - วัตถุประสงค์ของการทดสอบคือการกำหนดรหัสความต้องการ BDD ดีมาก ไม่เคยได้ยิน ATDD แต่อย่างรวดเร็วมันจะมีลักษณะเหมือนวิธีที่ผมใช้ TDD ปรับ
Steven A. Lowe

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

นอกจากนี้จากบทความ Wikipedia ที่คุณพูดถึง: "การฝึกฝนขั้นสูงของการพัฒนาแบบทดสอบขับเคลื่อนสามารถนำไปสู่ ​​ATDD โดยที่เกณฑ์ที่ลูกค้ากำหนดไว้เป็นแบบอัตโนมัติในการทดสอบการยอมรับ ... ] ด้วย ATDD ทีมพัฒนาตอนนี้มีเป้าหมายเฉพาะเพื่อตอบสนองการทดสอบการยอมรับซึ่งทำให้พวกเขามุ่งเน้นไปที่สิ่งที่ลูกค้าต้องการอย่างแท้จริงจากเรื่องราวของผู้ใช้ " ซึ่งดูเหมือนว่าATDDนั้นเน้นไปที่ความต้องการเป็นหลักไม่ใช่ TDD (หรือ UTDD ตามที่วางไว้)
guillaume31

@ ian31: คำถามของ OP เกี่ยวกับ 'การทดสอบหน่วยการทดสอบหลายร้อยครั้ง' แสดงถึงความสับสนของระดับ คุณสามารถใช้ TDD เพื่อสร้างโรงเก็บของได้หากต้องการ : D
Steven A. Lowe

3

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

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

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


2

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

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

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

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


1

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

  • หากคุณไม่แน่ใจเกี่ยวกับประสิทธิภาพคุณอาจต้องการเริ่มต้นด้วยการทดสอบการรวมสองสามอย่างที่ยืนยันประสิทธิภาพ

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


0

สำหรับฉันการทดสอบหน่วยยังเป็นโอกาสที่จะทำให้อินเทอร์เฟซภายใต้การใช้งาน "ของจริง" (เช่นเดียวกับการทดสอบตามหน่วยจริง!)

หากฉันถูกบังคับให้ตั้งค่าการทดสอบฉันต้องฝึกการออกแบบของฉัน สิ่งนี้จะช่วยให้สิ่งต่าง ๆ มีสติ (ถ้าบางสิ่งบางอย่างมีความซับซ้อนมากที่การเขียนการทดสอบสำหรับมันเป็นภาระสิ่งที่มันจะชอบที่จะใช้?)

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

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


0

ยินดีต้อนรับสู่นักพัฒนาความคิดสร้างสรรค์ของคณะละครสัตว์


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

- เขียนด้วยสัญชาตญาณของคุณ ไม่ใช่ด้วยจิตและจินตนาการของคุณ
- และหยุด
- ใช้แว่นขยายและตรวจสอบทุกคำที่คุณเขียน: คุณเขียน "ข้อความ" เพราะ "ข้อความ" อยู่ใกล้กับสตริง แต่ "คำกริยา", "คำคุณศัพท์"
หรือสิ่งที่ถูกต้องมากขึ้นเป็นสิ่งจำเป็นอ่านอีกครั้งและปรับวิธีการด้วยความรู้สึกใหม่.. หรือคุณเขียนโค้ดเกี่ยวกับอนาคต ลบออก
- แก้ไขทำงานอื่น ๆ (กีฬาวัฒนธรรมหรือสิ่งอื่น ๆ นอกธุรกิจ) กลับมาอ่านอีกครั้ง
- ทั้งหมดเข้ากันได้ดี
- ถูกต้องทำงานอื่นกลับมาอ่านอีกครั้ง
- ทั้งหมดเข้ากันได้ดีส่งผ่านไปยัง TDD
- ตอนนี้ทุกอย่างถูกต้องดี
- ลองใช้เกณฑ์มาตรฐานเพื่อชี้ให้เห็นสิ่งที่จะปรับให้เหมาะสมทำ

มีอะไรปรากฏขึ้น:
- คุณเขียนโค้ดเกี่ยวกับกฎทั้งหมด
- คุณได้รับประสบการณ์วิธีใหม่ในการทำงาน
- มีอะไรเปลี่ยนแปลงในใจคุณจะไม่มีวันกลัวการกำหนดค่าใหม่

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

แสดงความนับถือจาก PARIS
Claude

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