การทดสอบขับเคลื่อนการพัฒนา (TDD) มีประโยชน์ต่อโครงการโลกแห่งความเป็นจริงหรือไม่?


36

ฉันไม่ได้ใหม่ในการเขียนโปรแกรม ฉันได้รับการเข้ารหัส (อย่างจริงจัง) มานานกว่า 15 ปีแล้ว ฉันมักจะมีการทดสอบรหัสของฉัน อย่างไรก็ตามในช่วงไม่กี่เดือนที่ผ่านมาผมได้รับการเรียนรู้การออกแบบการทดสอบขับเคลื่อนการพัฒนา / (TDD) โดยใช้Ruby on Rails จนถึงตอนนี้ฉันไม่เห็นประโยชน์

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

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

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

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

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


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


3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtestนี่คือเรื่องราวจาก Uncle Bob เกี่ยวกับสถานการณ์ในโลกแห่งความเป็นจริงที่เขาเผชิญ
Hakan Deryal

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

1
"ฉันพบว่าฉันใช้เวลามากขึ้นในการพยายามดีบั๊กการทดสอบเพื่อให้พวกเขาพูดในสิ่งที่ฉันหมายถึงจริงๆกว่าที่ฉันทำการดีบั๊กโค้ดจริง" : แต่นี่ไม่ได้ประโยชน์อย่างแน่นอนหรือไม่ หลังจากนั้นคุณยังพบว่าคุณใช้เวลาในการดีบัก "รหัสจริง" เป็นจำนวนมากหรือไม่? ผู้เสนอของ TDD ยืนยันว่าเวลาที่ใช้ในการหาวิธีที่จะทำให้รหัสของคุณทดสอบได้จริง ๆ แล้วเป็นความพยายามในการออกแบบที่จะเป็นประโยชน์ต่อโค้ดของคุณ
Andres F.

คำตอบ:


26

บทความนี้แสดงให้เห็นว่า TDD เพิ่มเวลาในการพัฒนา 15-35% เพื่อเป็นการลดความหนาแน่นของข้อบกพร่อง 40-90% ในโครงการที่มีลักษณะคล้ายกัน

บทความอ้างถึงบทความฉบับเต็ม(pdf) - Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat และ Laurie Williams “ การตระหนักถึงการปรับปรุงคุณภาพด้วยการพัฒนาแบบทดสอบขับเคลื่อน: ผลลัพธ์และประสบการณ์ของสี่ทีมอุตสาหกรรม” ESE 2008

บทคัดย่อการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ (TDD) เป็นการฝึกการพัฒนาซอฟต์แวร์ที่ถูกใช้เป็นระยะเวลาหลายสิบปีด้วยการฝึกนี้วิศวกรซอฟต์แวร์จะวนรอบเป็นนาทีต่อนาทีระหว่างการเขียนการทดสอบที่ล้มเหลวของหน่วยและการเขียนรหัสการติดตั้งเพื่อผ่านการทดสอบเหล่านั้น การพัฒนา Testdriven เพิ่งเกิดขึ้นอีกครั้งในฐานะวิธีปฏิบัติที่สำคัญสำหรับการพัฒนาซอฟต์แวร์แบบว่องไว อย่างไรก็ตามหลักฐานเชิงประจักษ์เล็ก ๆ น้อย ๆ สนับสนุนหรือหักล้างยูทิลิตี้ของการปฏิบัตินี้ในบริบทอุตสาหกรรม กรณีศึกษาถูกดำเนินการกับทีมพัฒนาสามทีมที่ Microsoft และอีกทีมหนึ่งที่ IBM ซึ่งใช้ TDD ผลจากกรณีศึกษาระบุว่าความหนาแน่นข้อบกพร่องก่อนวางจำหน่ายของทั้งสี่ผลิตภัณฑ์ลดลงระหว่าง 40% และ 90% เมื่อเทียบกับโครงการที่คล้ายกันซึ่งไม่ได้ใช้วิธีฝึก TDD จิตใจ,

บทความฉบับเต็มยังสรุปการศึกษาเชิงประจักษ์ที่เกี่ยวข้องกับ TDD และผลลัพธ์ระดับสูง (ส่วนที่3 งานที่เกี่ยวข้อง ) รวมถึง George and Williams 2003, Müllerและ Hagner (2002), Erdogmus et al. (2005), Müllerและ Tichy (2001), Janzen และ Seiedian (2006)


2
ตามการอภิปรายเกี่ยวกับ Meta.StackOverflowคุณสามารถเพิ่มข้อมูลเพิ่มเติมจากบทความที่อาจเกี่ยวข้องกับผู้ถามรวมถึงคนในอนาคตที่พบคำถามนี้หรือไม่
Thomas Owens

2
@ThomasOwens ฉันคิดว่าข้อสรุป ("TDD เพิ่มเวลาในการพัฒนา 15-35% เพื่อเป็นการลดความหนาแน่นของข้อบกพร่อง 40-90%") เป็นข้อมูลเพิ่มเติมที่ตอบคำถามเดิม <_ <

4
โพสต์นี้ถูกตั้งค่าสถานะเนื่องจากไม่มีข้อมูลเพียงพอ ฉันยังไม่ได้อ่านกระดาษ แต่ปรากฏว่าผู้คนต้องการข้อมูลเพิ่มเติมในเนื้อหาของคำตอบ อาจพูดคุยเพิ่มเติมเกี่ยวกับเงื่อนไขเฉพาะที่ใช้ในการศึกษา?
Thomas Owens

99% ของสถิติทั้งหมดเป็นตัวละคร : P แต่จริงๆแล้วมันเกี่ยวกับบริบท กับทีมแบบไหน? ฝูงใหญ่ของ devs Java ปานกลาง? ใช่ฉันเชื่อว่า TDD จะช่วยพวกเขาในการเพิ่มผลผลิต แต่นั่นไม่ได้หมายความว่าการมีทักษะทางสถาปัตยกรรมในการออกแบบและให้ความสำคัญกับรหัสที่มีประสิทธิภาพในตอนแรกจะไม่ช่วยพวกเขามากขึ้นและ IMO การทดสอบ TDD ครั้งแรกสามารถป้องกันพวกเขาจากการเรียนรู้วิธีการทำอย่างถูกต้อง และใช่ฉันได้ยินว่ามันช่วยในการออกแบบ ในระดับหนึ่งอาจเป็นจริง แต่ก็ยังคงล้มเหลวในการรับทราบและช่วยเหลือวงดนตรีสำหรับปัญหาราก IMO
Erik Reppen

น่าจะดีถ้ามีเอกสารอื่น ๆ เพิ่มเข้ามาจากACM Digital Libraryหรือคำสำคัญที่ใช้สำหรับเครื่องมือค้นหาที่เพิ่มเข้ามา เราต้องการคำตอบที่เข้มงวดมากขึ้นเมื่อพูดถึงความคล่องแคล่วและ TDD
Rudolf Olah

16

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

ฉันทำงาน TDD มาสามปีที่ผ่านมาและประสบการณ์ของฉันก็ตรงกันข้าม ฉันใช้เวลาน้อยลงในการเขียนการทดสอบหน่วยที่ฉันจะต้องดีบักรหัสหากฉันไม่ได้เขียนการทดสอบหน่วย

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

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

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

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

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

แต่มันทำงานได้ดีในโครงการจริง?

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

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

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

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


9

เราได้รับประโยชน์อย่างมากมาย

เราเป็น Tier 1 Merchant ซึ่งหมายความว่าเราประมวลผลธุรกรรมการชำระเงินมากกว่าหกล้านรายการต่อปี

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

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

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

โดยส่วนตัวฉันคิดว่ามันยากที่จะเขียนตรรกะใด ๆ ก่อนที่จะเขียนการทดสอบ ต้องบอกว่ามันใช้เวลาสักครู่ในการเริ่มคิดด้วยวิธี TDD

การอ้างอิง Visa PCI: http://usa.visa.com/merchants/risk_management/cisp_merchants.html


3
"เราจะตอบกลับและแก้ไขปัญหาเหล่านี้ในที่สุด" - อาจไม่ใช่ ... ไม่ใช่เว้นแต่พวกเขาจะตบคุณด้วยข้อผิดพลาดที่น่ากลัว พื้นที่เหล่านี้จะกลายเป็นแกนหลักสำหรับทุกสิ่งและจะเป็นแนวทางในการออกแบบทั้งหมดเพราะไม่มีใครต้องการลงทุนทรัพยากรเพื่อทำซ้ำและไม่มีใครต้องการบังคับให้มีการเปลี่ยนแปลงใด ๆ ที่อาจทำสิ่งที่ไม่ดี เกิดขึ้นทุกครั้ง: P
Edward Strange

คุณกำลังเดาเมื่อฉันบอกคุณสิ่งที่เกิดขึ้นภายใน บริษัท เมื่อเราคอมมิทเราสามารถคอมมิทโค้ดด้วยความครอบคลุมโค้ด 70% สิ่งนี้จะเพิ่มขึ้นอย่างต่อเนื่องโดยผู้นำ CI ภายในไม่กี่เดือนเกณฑ์การครอบคลุมโค้ดขั้นต่ำจะเพิ่มขึ้นเล็กน้อย หลังจากนั้นจะไม่มีทางเลือก แต่จะแนะนำการทดสอบเพิ่มเติม
CodeART

7

แม้ว่าบางคนอาจคิดว่าการทดสอบเป็นวิธีหนึ่งที่ทำมากเกินไป แต่ฉันคิดว่ามันคุ้มค่ากับปัญหาในบางกรณี

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

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

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

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


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

6

ข้อดีของ TDD คือคุณต้องหาวิธีการเรียกรหัสของคุณก่อนที่จะเขียนรหัสจริง

กล่าวอีกนัยหนึ่ง TDD ช่วยในการออกแบบ API ของคุณ

จากประสบการณ์ของฉันผลลัพธ์นี้ทำให้ API ดีขึ้นซึ่งจะให้โค้ดที่ดีกว่า


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

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

กรณีทดสอบกำลังเรียกใช้ข้อมูลจำเพาะรุ่นและช่วยให้คุณเห็นวิธีเรียก API ของคุณได้อย่างง่ายดาย นี่อาจเป็นรูปแบบเดียวที่มีประโยชน์ที่สุดของ"HOW" -เอกสารที่ฉันเคยเห็น (เปรียบเทียบกับ"WHY" -เอกสารเช่น JavaDoc) ตามที่คุณแน่ใจว่าถูกต้อง (มิฉะนั้นการทดสอบจะล้มเหลว)

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


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

3
เห็นด้วย แต่ฉันไม่มีชื่อเสียงที่จะลงคะแนน นี่เป็นเพียง "TDD ให้ผลลัพธ์ที่ดีกว่า" โดยไม่มีตัวอย่างของโครงการ TDD ที่ได้รับในการบำรุงรักษาเพื่อสำรองคำตอบที่ฉันต้องการหลีกเลี่ยง
James

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

@delnan "ฉันกล้าลงคะแนน" - คำศัพท์ที่น่าสนใจ การแก้ไขของคุณตกอยู่ในรสนิยมของคุณหรือไม่?

ใช่ฉันลบ downvote ทันทีที่ฉันสังเกตเห็น

5

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

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

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

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

คุณพูดสิ่งต่อไปนี้ในคำถามของคุณ:

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

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

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

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

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

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

TL: DR - ใช่พวกเขาเป็นความช่วยเหลือโลกแห่งความจริง แต่พวกเขาเป็นการลงทุน ประโยชน์จะชัดเจนขึ้นในภายหลังเท่านั้น


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

น่าเสียดายที่ไม่มีใครดูเหมือนจะสร้างการทดสอบหน่วยอย่างน้อยก็ไม่ได้อยู่ในรหัสใด ๆ ที่ฉันได้รับมาจากนักพัฒนาก่อนหน้านี้ ชีวิตของฉันคงจะง่ายกว่านี้ถ้ามี ฉันขอแนะนำให้คุณตรวจสอบหนังสือในลิงค์ซึ่งมีตัวอย่างในโลกแห่งความเป็นจริงถึงแม้ว่ามันจะมีไว้สำหรับ PHP แทนที่จะเป็น Rails amazon.com/…
GordonM

ฉันเป็นนักวิจารณ์ที่กว้างขวางเกี่ยวกับการใช้งานทั่วไป แต่ฉันจะไม่ผิดใครที่ใช้วิธีการนี้ในระบบการเงินแบบฝังหรือวิกฤต
Erik Reppen

4

ฉันใช้ TDD บ่อยครั้งในที่ทำงาน ประสบการณ์ของฉันที่ justifies TDD ตัวเองเพราะคุณไม่ต้องจ่ายเพิ่มเวลาหรือความพยายามของคุณบันทึกมัน

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

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

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

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

  • แม้ว่าฉันจะใช้ดีบักเกอร์มันก็เร็วกว่ามากในการดีบักการดำเนินการทดสอบกว่าแอปพลิเคชันทั้งหมด

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


คุณภาพฟรี!
MathAttack

2
คุณภาพไม่ดีมีราคาแพง!
Wolfgang

3

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


2

ฉันรู้ว่าฉันได้รับประโยชน์เป็นการส่วนตัวโดยการเป็นสองเท่าของผู้พัฒนาเพื่อนของฉันและเขียนข้อบกพร่องน้อยกว่าครึ่งที่พวกเขาทำเพราะพวกเขาไม่ได้ทำ TDD คนที่น่าจะดีกว่าฉันแม้แต่ ... ฉันทำได้ดีกว่าพวกเขาอย่างน้อย 2 เท่า

ฉันไม่ได้ไปที่นั่นทันที ฉันเขียนโค้ดออกจากข้อมือได้ค่อนข้างดีและไม่มีสายรัดข้อมือ ดูเหมือนว่าเป็นเรื่องใหญ่ที่จะเขียนอึพิเศษทั้งหมดนี้ แต่มันทำหลายสิ่งรวมถึง (ไม่ จำกัด เฉพาะ):

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

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


2

คำตอบคือใช่ ใน บริษัท ของฉันเราได้พัฒนาแอปพลิเคชั่น C ++ มากว่า 20 ปี ปีที่แล้วเราเข้าสู่ TDD ในโมดูลใหม่บางส่วนและอัตราข้อบกพร่องลดลงอย่างมีนัยสำคัญ เราชอบมันมากจนบางคนยังเพิ่มการทดสอบในรหัสเดิมทุกครั้งที่เราเปลี่ยนบางสิ่งที่นั่น

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

ฉันยังไม่ได้ทำ Rails TDD มากนัก แต่ฉันทำได้ใน C ++, C #, Java และ Python มาก ฉันสามารถบอกคุณได้ว่ามันใช้งานได้แน่นอน ฉันเดาว่าคุณจะใช้เวลาส่วนใหญ่คิดเกี่ยวกับชื่อทดสอบเพราะคุณไม่มั่นใจพอ เขียนการทดสอบของคุณก่อน แต่ให้ความคิดสร้างสรรค์ของคุณลื่นไหล ...

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

เวลาสำหรับเคล็ดลับ

เคล็ดลับ # 1

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

เคล็ดลับ # 2

เริ่มต้นการทดสอบในชั้นเรียนใหม่ด้วยการทดสอบ "canCreate" เพียงเพื่อตั้งความคิดของคุณในทิศทางที่ถูกต้องเช่นเดียวกับใน "โอเคฉันกำลังทำงานในชั้นเรียนนี้ในขณะนี้ ... ถูกต้อง"

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

และจำไว้ว่า

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

ลองอีกนัดดู และฉันขอแนะนำให้ดูClean Code Castsโดยเฉพาะเกี่ยวกับ TDD


1

โลกแห่งความจริงตัวอย่างที่ไม่สำคัญ:

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


-1

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

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

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

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

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

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

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

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

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


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

1
มันตอบ แต่เนื่องจากคุณไม่แบ่งปันความคิดเห็นของฉันคุณให้ -1 กับมัน :) โดยทั่วไปใครก็ตามที่ไม่พยายามแสดงค่าของ TDD จะให้คำตอบที่ไม่ต้องการจากมุมมองของคุณ;) ให้ฉันเดา . คุณเป็นผู้เผยแพร่ศาสนา TDD ใช่ไหม? :) อย่างไรก็ตามคำถามที่แท้จริงของผู้แต่งคือว่า TDD จ่ายออกหรือไม่ คุณไม่ต้องฝึกฝน TDD เพื่อตอบคำถามนั้น Fortran จ่ายเงินเพื่อเขียนเว็บแอปหรือไม่ คุณเคยลองก่อนตอบไหม?
rosenfeld

ฉันไม่ได้มีความคิดเห็นเกี่ยวกับ TDD และฉันไม่ได้ใช้การโหวตเหมือน / ไม่ชอบ (เป็นเว็บไซต์คำถามและคำตอบไม่ใช่ Facebook) ตามการอ่านของฉัน "คำตอบ" นี้ไม่ได้ตอบคำถามที่ถามเลยไม่ว่าจะเป็นในทางบวกหรือในทางลบ
gnat

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

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