ฉันไม่เข้าใจว่า TDD ช่วยให้ฉันได้รับการออกแบบที่ดีได้อย่างไรถ้าฉันต้องการการออกแบบเพื่อเริ่มการทดสอบ


50

ฉันพยายามคลุมศีรษะด้วย TDD โดยเฉพาะในส่วนของการพัฒนา ฉันได้ดูหนังสือบางเล่ม แต่หนังสือที่ฉันพบส่วนใหญ่จัดการกับส่วนทดสอบ - ประวัติของ NUnit ทำไมการทดสอบจึงดี Red / Green / Refactor และวิธีการสร้างเครื่องคำนวณสตริง

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

เพื่ออธิบายให้นึกภาพ 3 ข้อเหล่านี้:

  • แคตตาล็อกต้องมีรายการผลิตภัณฑ์
  • แค็ตตาล็อกควรจดจำผลิตภัณฑ์ที่ผู้ใช้ดู
  • ผู้ใช้ควรสามารถค้นหาผลิตภัณฑ์ได้

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

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

ตามSOLIDฉันต้องการ UserService แต่ถ้าฉันออกแบบระบบที่ไม่มี TDD ฉันอาจต้องใช้ Single-Method Services ทั้งหมด TDD ไม่ได้ตั้งใจจะทำให้ฉันค้นพบการออกแบบของฉันตั้งแต่แรก?

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


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

3
@gnat: เป็นคำถามที่ว่าทำไมหนังสือ TDD ไม่ทำให้ขั้นตอนการออกแบบชัดเจนขึ้น
Robert Harvey

4
@gnat: มันเป็นการแก้ไขของคุณไม่ใช่ของฉัน :) ดูการเปลี่ยนแปลงของฉันกับชื่อของคำถามและเนื้อหา
Robert Harvey

9
หากคุณได้อ่านงานของ Robert C. Martin หรือดูวิดีโอของเขาคุณจะเห็นว่าเขามักจะมีการออกแบบในใจ แต่เขาไม่ได้แต่งงานกับมัน เขาเชื่อว่าแนวคิดของการออกแบบที่ถูกต้องมาก่อนจะเกิดขึ้นจากการทดสอบของเขา แต่เขาไม่ได้บังคับให้ทำ และในที่สุดบางครั้งการออกแบบก็ทำและบางครั้งก็ไม่ได้ จุดของฉันที่นี่คือประสบการณ์ก่อนหน้านี้ของคุณจะแนะนำคุณ แต่การทดสอบควรผลักดันคุณ การทดสอบควรจะสามารถพัฒนาหรือหักล้างการออกแบบของคุณ
Anthony Pegram

3
ดังนั้นมันจึงไม่เกี่ยวกับการทดสอบ แต่เป็นการออกแบบ มีเพียงมันเท่านั้นที่ไม่ได้ช่วยให้คุณออกแบบจริงๆเท่าที่จะช่วยคุณตรวจสอบการออกแบบ แต่นั่นไม่ใช่การทดสอบ! @ # $ ing?
Erik Reppen

คำตอบ:


17

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

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


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


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


Robert Harvey ได้เพิ่มสิ่งนี้ลงในความคิดเห็นที่ควรค่าแก่คำตอบ:

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


31
@MichaelStum: น่าเสียดายที่ฉันคิดว่านี่เป็นความเข้าใจที่คลาดเคลื่อนเกี่ยวกับ TDD: คุณไม่สามารถสร้างสถาปัตยกรรมซอฟต์แวร์ได้ด้วยการเขียนการทดสอบหน่วยและทำให้พวกเขาผ่านไป การทดสอบหน่วยการเขียนมีผลต่อการออกแบบ แต่ไม่ได้สร้างการออกแบบ คุณต้องทำอย่างนั้น
Robert Harvey

4
@RobertHarvey, JimmyHoffa: ถ้าฉันสามารถโหวตความคิดเห็นของคุณได้ 100 ครั้งฉันก็จะทำ!
Doc Brown

9
@ Robert Harvey: ฉันดีใจที่คุณเขียนเกี่ยวกับความเข้าใจผิดที่เกิดขึ้นบ่อยครั้งนี้: ฉันได้ยินบ่อยเกินไปว่าคน ๆ หนึ่งต้องนั่งลงและเขียนการทดสอบหน่วยต่าง ๆ และการออกแบบก็จะ "ปรากฏ" ตามธรรมชาติ และถ้าการออกแบบของคุณไม่ดีอาจเป็นเพราะคุณเขียนหน่วยทดสอบไม่เพียงพอ ฉันเห็นด้วยกับคุณว่าการทดสอบเป็นเครื่องมือในการระบุและตรวจสอบข้อกำหนดสำหรับการออกแบบของคุณ แต่ "คุณต้องทำ" การออกแบบด้วยตัวเอง ฉันเห็นด้วยอย่างยิ่ง
Giorgio

4
@Giorgo, RobertHarvey: +1000 ถึง RobertHarvey จากฉันเช่นกัน น่าเสียดายที่การเข้าใจผิดนั้นเป็นเรื่องธรรมดามากพอที่ผู้ปฏิบัติงาน TDD / Agile บางคนเชื่อว่าเป็นเรื่องจริง เหมือนเช่นที่พวกเขาหลอกคุณสามารถ "วิวัฒนาการ" ซูโดกุแก้จาก TDD โดยไม่มีความรู้โดเมนหรือการวิเคราะห์ใด ฉันสงสัยว่ารอนเจฟฟรีส์จะตีพิมพ์ผลการติดตามเกี่ยวกับข้อ จำกัด ของ TDD หรืออธิบายว่าทำไมเขาจึงหยุดการทดลองโดยไม่มีข้อสรุปหรือบทเรียนที่ได้เรียนรู้
Andres F.

3
@Andres F: ฉันรู้เรื่องราวเกี่ยวกับซูโดกุและฉันคิดว่ามันน่าสนใจมาก ฉันคิดว่านักพัฒนาบางคนทำผิดที่คิดว่าเครื่องมือ (เช่น TDD หรือ SCRUM) สามารถแทนที่ความรู้ในโดเมนและความพยายามของพวกเขาเองและคาดหวังว่าด้วยการใช้วิธีการทางกลไกโดยเฉพาะซอฟต์แวร์ที่ดีจะเกิดขึ้นอย่างน่าอัศจรรย์ พวกเขามักจะเป็นคนที่ไม่ชอบใช้เวลามากเกินไปในการวิเคราะห์และออกแบบและชอบที่จะเขียนโค้ดโดยตรง สำหรับพวกเขาการทำตามวิธีการเฉพาะเป็นข้อแก้ตัวสำหรับการออกแบบที่ไม่เหมาะสม แต่นี่เป็น IMHO การใช้ TDD ในทางที่ผิด
Giorgio

8

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

มันทำยังไง?

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

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

มันง่ายจริงๆ มันไม่ใช่เครื่องมือออกแบบเวทย์มนตร์


6

ฉันพยายามคลุมหัวของฉันรอบ ๆ TDD ... เพื่ออธิบายให้นึกภาพ 3 ข้อนี้

  • แคตตาล็อกต้องมีรายการผลิตภัณฑ์
  • แค็ตตาล็อกควรจดจำผลิตภัณฑ์ที่ผู้ใช้ดู

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

  • ผู้ใช้ควรสามารถค้นหาผลิตภัณฑ์ได้

อย่างไร? โดยชื่อ? ตามแบรนด์? ขั้นตอนแรกในการพัฒนาโดยอาศัยการทดสอบคือการกำหนดการทดสอบตัวอย่างเช่น:

browse to http://ourcompany.com
enter "cookie" in the product search box
page should show "chocolate-chip cookies" and "oatmeal cookies"

>

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

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

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


ตกลงไม่ProductServiceได้ แต่ TDD บอกคุณได้อย่างไรว่าคุณต้องการฐานข้อมูลและ ORM
Robert Harvey

4
@ Robert: มันไม่ได้ เป็นการตัดสินใจออกแบบตามการตัดสินใจของฉันในวิธีที่มีประสิทธิภาพที่สุดเพื่อตอบสนองความต้องการ แต่การตัดสินใจสามารถเปลี่ยนแปลงได้
วินไคลน์

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

ฉันคิดว่าการทดสอบ 'เพิ่มผลิตภัณฑ์ รีบูทคอมพิวเตอร์และรีสตาร์ทระบบ ควรเพิ่มผลิตภัณฑ์ที่ยังคงมองเห็นได้ ' แสดงตำแหน่งที่ต้องการฐานข้อมูลบางประเภทมาจาก (แต่อาจเป็นไฟล์แบบแฟลตหรือ XML)
yatima2975

3

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

ตัวอย่างบางส่วนที่ฉันเคยพบเจอสิ่งนี้ในอดีต:

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

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

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

  • สถานการณ์ใด ๆ ที่คุณมีกลไกพื้นฐานไม่เพียงพอที่จะเพิ่มฟีเจอร์ที่ทดสอบได้โดยไม่ต้องเขียนบิตที่ไม่สามารถทดสอบได้พื้นฐานก่อนเช่นระบบย่อยของดิสก์หรืออินเตอร์เฟสการสื่อสารระดับ tcpip

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

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


1

ผมเชื่อว่า TDD เป็นวิธีการที่มีคุณค่ามากกับรายละเอียดของการออกแบบของระบบ - เช่น APIs และรูปแบบวัตถุ อย่างไรก็ตามเพื่อให้ได้มาถึงจุดหนึ่งในโครงการที่คุณจะเริ่มใช้ TDD คุณต้องมีภาพใหญ่ของการออกแบบที่จำลองในแฟชั่นแล้วและคุณต้องมีภาพขนาดใหญ่ของสถาปัตยกรรมที่จำลองในแฟชั่นบางอย่างแล้ว @ user414076 ถอดความ Robert Martin ว่ามีแนวคิดในการออกแบบ แต่ไม่ได้แต่งงานกับมัน เผง บทสรุป - TDD ไม่ได้เป็นเพียงกิจกรรมการออกแบบเท่านั้น แต่เป็นรายละเอียดของการออกแบบ TDD จะต้องนำหน้าด้วยกิจกรรมการออกแบบอื่น ๆ และสอดคล้องกับแนวทางโดยรวม (เช่น Agile) ที่เน้นการออกแบบและพัฒนาโดยรวม

FYI - หนังสือสองเล่มที่ฉันแนะนำในหัวข้อที่ให้ตัวอย่างที่ชัดเจนและเป็นจริง:

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

การพัฒนาที่ขับเคลื่อนด้วยการทดสอบคู่มือเชิงปฏิบัติ - การเดินอย่างช้าๆและเป็นขั้นเป็นตอนผ่านการพัฒนาแอพขนาดเล็กที่สมบูรณ์


0

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

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

นอกจากนี้ยังช่วยให้คิดว่าหน่วยความล้มเหลวเป็นรหัส "ยังไม่เสร็จ" แทนที่จะเป็นรหัส "เสีย" TDD ช่วยให้หน่วยที่ยังไม่เสร็จ (ความล้มเหลวที่คาดหวัง) แต่ช่วยลดการเกิดขึ้นของหน่วยงานที่เสียหาย (ความล้มเหลวที่ไม่คาดคิด)


1
ฉันยอมรับว่านี่เป็นเวิร์กโฟลว์ที่ถูกต้อง แต่ไม่ได้อธิบายว่าสถาปัตยกรรมระดับสูงสามารถเกิดขึ้นได้จากเวิร์กโฟลว์ดังกล่าวได้อย่างไร
Robert Harvey

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

0

ในคำถามมันระบุไว้:

... หนังสือหลายเล่มดึงกระต่ายเวทย์มนตร์ออกมาจากหมวกและกระโดดลงไปใน "การทดสอบบริการผลิตภัณฑ์" แต่พวกเขาไม่ได้อธิบายว่าพวกเขาสรุปได้อย่างไรว่ามี ProductService ตั้งแต่แรก

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


0

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

เกี่ยวกับการออกแบบฉันอ้างถึงหนังสือ Robert C. Martin (การพัฒนาแบบ Agile) แต่ยังรวมถึงรูปแบบของ Enterprise Application Architecture และ Martin Domain Design ต่อมาโดยเฉพาะอย่างยิ่งเป็นระบบมากในการดึงนิติบุคคลและความสัมพันธ์ออกจากข้อกำหนด

จากนั้นเมื่อคุณได้รับความรู้สึกที่ดีของตัวเลือกที่มีให้คุณในการจัดการเอนทิตีเหล่านั้นคุณสามารถป้อนฟีด TDD ของคุณ


0

TDD ไม่ได้ตั้งใจจะทำให้ฉันค้นพบการออกแบบของฉันตั้งแต่แรก?

เลขที่

คุณจะทดสอบสิ่งที่คุณไม่ได้ออกแบบมาก่อนได้อย่างไร

เพื่ออธิบายให้นึกภาพ 3 ข้อเหล่านี้:

  • แคตตาล็อกต้องมีรายการผลิตภัณฑ์
  • แค็ตตาล็อกควรจดจำผลิตภัณฑ์ที่ผู้ใช้ดู
  • ผู้ใช้ควรสามารถค้นหาผลิตภัณฑ์ได้

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

คุณต้องรู้ว่าอะไรคือค่าคงที่ของระบบของคุณ

ความต้องการจะเป็นเช่น:

  • ลูกค้าสามารถสั่งซื้อผลิตภัณฑ์จำนวนหนึ่งได้หากมีสินค้าเพียงพอในสต็อก

ดังนั้นหากนี่เป็นข้อกำหนดเพียงอย่างเดียวคุณอาจมีคลาสที่ชอบ:

public class Product {

  private int quantity;

  public Product(int initialQuantity) {
    this.quantity = initialQuantity;
  }

  public void order(int quantity) {
    // To be implemented.
  }

}

จากนั้นใช้ TDD คุณจะเขียนกรณีทดสอบก่อนที่จะใช้วิธีการ order ()

public void ProductTest() {

    public void testCorrectOrder() {

        Product p = new Product(10);
        p.order(3);
        p.order(4);

    }

    @Expect(ProductOutOfStockException)
    public void testIncorrectOrder() {

        Product p = new Product(10);
        p.order(7);
        p.order(4);

    }

}

ดังนั้นการทดสอบครั้งที่สองจะล้มเหลวจากนั้นคุณสามารถใช้วิธีการสั่งซื้อ () ตามที่คุณต้องการ


0

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


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

-3

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

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