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


30

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

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

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

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


คุณหมายถึงเทคนิคย่อย TDD ที่เรียกว่าการวิเคราะห์ตำแหน่ง ? โดย "วิธีการแก้ปัญหาที่ยอมรับได้" คุณหมายถึงหนึ่งที่ถูกต้องหรือหนึ่งที่สามารถบำรุงรักษา / สง่างาม / อ่านได้หรือไม่
guillaume31

6
ฉันคิดว่านี่เป็นปัญหาที่แท้จริง เนื่องจากเป็นเพียงความคิดเห็นของฉันฉันจะไม่เขียนคำตอบ แต่ใช่เนื่องจาก TDD ถูกขนานนามว่าเป็นแบบฝึกการออกแบบมันเป็นข้อบกพร่องที่สามารถนำไปสู่ ​​maxima ท้องถิ่นหรือไม่มีวิธีแก้ปัญหาเลย ฉันว่าโดยทั่วไป TDD ไม่เหมาะสำหรับการออกแบบอัลกอริทึม ดูการอภิปรายที่เกี่ยวข้องกับข้อ จำกัด ของ TDD: การแก้ Sudoku ด้วย TDDซึ่ง Ron Jeffries ทำให้ตัวเองในขณะที่ทำงานในแวดวงและ "ทำ TDD" ในขณะที่ Peter Norvig ให้วิธีการแก้ปัญหาจริงโดยการรู้เรื่องจริง
Andres F.

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

2
มีปัญหาอยู่ แต่ไม่ จำกัด เพียง TDD หรือแม้กระทั่ง Agile การเปลี่ยนแปลงข้อกำหนดซึ่งหมายความว่าการออกแบบซอฟต์แวร์ที่เขียนไว้ก่อนหน้านี้จะต้องมีการเปลี่ยนแปลงเกิดขึ้นตลอดเวลา
RemcoGerlich

@ guillaume31: ไม่จำเป็นต้องใช้การวิเคราะห์สามเหลี่ยม แต่ใช้เทคนิคใด ๆ ในการทำซ้ำในระดับซอร์สโค้ด โดยวิธีการแก้ปัญหาที่ยอมรับได้ฉันหมายถึงสิ่งหนึ่งที่ผ่านการทดสอบทั้งหมดและสามารถบำรุงรักษาได้ดีพอสมควร ..
Frank Puffer

คำตอบ:


8

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

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

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

ฉันสามารถจินตนาการถึงสถานการณ์ที่สิ่งนี้สามารถเกิดขึ้นได้ในความเป็นจริง: เมื่อคุณเลือกสถาปัตยกรรมที่ผิดในแบบที่คุณต้องสร้างการทดสอบที่มีอยู่ทั้งหมดของคุณอีกครั้งตั้งแต่เริ่มต้น ให้บอกว่าคุณเริ่มใช้กรณีทดสอบ 20 ข้อแรกในการเขียนโปรแกรมภาษา X บนระบบปฏิบัติการ A โชคไม่ดีที่ข้อกำหนดที่ 21 ระบุว่าโปรแกรมทั้งหมดต้องทำงานบนระบบปฏิบัติการ B โดยที่ X ไม่สามารถใช้งานได้ ดังนั้นคุณต้องทิ้งงานส่วนใหญ่ของคุณและปรับใช้ภาษา Y ใหม่ (แน่นอนคุณจะไม่ทิ้งรหัสทั้งหมด แต่ส่งไปยังภาษาและระบบใหม่)

สิ่งนี้สอนเราแม้ว่าจะใช้ TDD เป็นความคิดที่ดีที่จะทำการวิเคราะห์และออกแบบโดยรวมก่อน อย่างไรก็ตามสิ่งนี้ก็เป็นจริงสำหรับวิธีการอื่นใดดังนั้นฉันไม่เห็นว่านี่เป็นปัญหา TDD โดยธรรมชาติ และสำหรับงานการเขียนโปรแกรมส่วนใหญ่ในโลกแห่งความเป็นจริงคุณสามารถเลือกสถาปัตยกรรมมาตรฐาน (เช่นภาษาโปรแกรม X, ระบบปฏิบัติการ Y, ระบบฐานข้อมูล Z บนฮาร์ดแวร์ XYZ) และคุณสามารถมั่นใจได้ว่าวิธีการทำซ้ำหรือเปรียวเช่น TDD จะไม่นำคุณไปสู่ความตาย

การอ้างถึง Robert Harvey: "คุณไม่สามารถสร้างสถาปัตยกรรมจากการทดสอบหน่วยได้" หรือ pdr: "TDD ไม่เพียง แต่ช่วยฉันในการออกแบบขั้นสุดท้ายที่ดีที่สุดเท่านั้น แต่ยังช่วยให้ฉันไปถึงที่นั่นด้วยความพยายามน้อยลง"

ดังนั้นสิ่งที่คุณเขียน

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

อาจกลายเป็นจริง - เมื่อคุณเลือกสถาปัตยกรรมที่ไม่ถูกต้องคุณจะไม่สามารถเข้าถึงโซลูชันที่ต้องการได้

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


20

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

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

  1. ครบถ้วนปัญหา: วิธีการหลายการทดสอบมีความจำเป็นที่จะสมบูรณ์อธิบายระบบหรือไม่? "การเข้ารหัสตามตัวอย่างกรณี" เป็นวิธีที่สมบูรณ์ในการอธิบายระบบหรือไม่?

  2. แข็งปัญหา: สิ่งที่ทดสอบอินเตอร์เฟซที่จะต้องมีอินเตอร์เฟซที่เปลี่ยนไม่ได้ การทดสอบแสดงถึงความจริงที่ไม่เปลี่ยนแปลงจำได้ น่าเสียดายที่ความจริงเหล่านี้ไม่เป็นที่รู้จักสำหรับรหัสส่วนใหญ่ที่เราเขียนเท่านั้นที่ดีที่สุดสำหรับวัตถุที่หันเข้าหาภายนอก

  3. ความเสียหายทดสอบปัญหา: เพื่อให้ยืนยันทดสอบเราอาจจำเป็นต้องเขียนโค้ดด้อย (performant น้อยตัวอย่างเช่น) เราจะเขียนการทดสอบอย่างไรเพื่อให้รหัสนั้นดีเท่าที่ควรจะเป็น?


แก้ไขเพื่อแก้ไขความคิดเห็น: นี่เป็นตัวอย่างของการกระตุ้นค่าสูงสุดในท้องถิ่นสำหรับฟังก์ชั่น "double" ผ่านการรีแฟคเตอร์

ทดสอบ 1:เมื่ออินพุทเป็น 0 ให้คืนศูนย์

การดำเนินงาน:

function double(x) {
  return 0; // simplest possible code that passes tests
}

Refactoring:ไม่จำเป็น

ทดสอบ 2:เมื่ออินพุทคือ 1 คืนค่า 2

การดำเนินงาน:

function double(x) {
  return x==0?0:2; // local maximum
}

Refactoring:ไม่จำเป็น

ทดสอบ 3:เมื่ออินพุทคือ 2 คืนค่า 4

การดำเนินงาน:

function double(x) {
  return x==0?0:x==2?4:2; // needs refactoring
}

refactoring:

function double(x) {
  return x*2; // new maximum
}

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

3
ฉันไม่มั่นใจว่าการเปลี่ยนโครงสร้างใหม่เป็นวิธีการสรุปรหัส (นอกพื้นที่ "รูปแบบการออกแบบ" ของเทียม) หรือหลีกเลี่ยงการใช้สูงสุดในพื้นที่ การปรับโครงสร้างโค้ดขึ้นใหม่ แต่จะไม่ช่วยให้คุณค้นพบทางออกที่ดีกว่า
Andres F.

2
@Sklivvz เข้าใจ แต่ฉันไม่คิดว่ามันจะใช้วิธีนอกตัวอย่างของเล่นเช่นที่คุณโพสต์ นอกจากนี้ยังช่วยคุณด้วยว่าฟังก์ชั่นของคุณชื่อ "double"; ในแบบที่คุณรู้คำตอบแล้ว TDD ช่วยแน่นอนเมื่อคุณรู้คำตอบไม่มากก็น้อย แต่ต้องการเขียนว่า "หมดจด" มันจะไม่ช่วยในการค้นหาอัลกอริทึมหรือการเขียนโค้ดที่ซับซ้อนจริงๆ นี่คือสาเหตุที่ Ron Jeffries ล้มเหลวในการแก้ปัญหา Sudoku ด้วยวิธีนี้; คุณไม่สามารถใช้อัลกอริทึมที่คุณไม่คุ้นเคยโดย TDD โดยไม่ทำให้สับสน
Andres F.

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

2
@Sklivvz "ตราบใดที่คุณสามารถเขียนแบบทดสอบที่เหมาะสม" ได้อย่างแม่นยำจุด: ดูเหมือนว่าขอให้ฉันคำถาม สิ่งที่ผมพูดคือว่าคุณมักจะไม่สามารถ ความคิดเกี่ยวกับขั้นตอนวิธีการหรือแก้ไม่ได้ทำง่ายขึ้นโดยการเขียนการทดสอบครั้งแรก คุณต้องมองไปที่ภาพรวมเป็นครั้งแรก แน่นอนว่าการลองใช้สถานการณ์เป็นสิ่งที่จำเป็น แต่ TDD นั้นไม่ได้เกี่ยวกับการเขียนสถานการณ์: TDD นั้นเกี่ยวกับการทดสอบการออกแบบ ! คุณไม่สามารถผลักดันการออกแบบตัวแก้ของ Sudoku (หรือตัวแก้ปัญหาใหม่สำหรับเกมอื่น) โดยเขียนการทดสอบก่อน ในฐานะที่เป็นพยานหลักฐานที่ไม่เพียงพอ (ซึ่งไม่เพียงพอ): เจฟฟรีย์ทำไม่ได้
Andres F.

13

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

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

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


13

ในคำตอบของเขา @Sklivvz ให้เหตุผลว่าปัญหานั้นไม่มีอยู่จริง

ฉันต้องการที่จะยืนยันว่ามันไม่สำคัญ: สถานที่ตั้งพื้นฐาน (และ raison d'retre) ของวิธีการทำซ้ำโดยทั่วไปและ Agile และโดยเฉพาะอย่างยิ่ง TDD โดยเฉพาะอย่างยิ่งนั่นไม่เพียง แต่เป็นสิ่งที่ดีที่สุดในโลก ไม่เป็นที่รู้จัก ดังนั้นในคำอื่น ๆ : แม้ว่าจะเป็นปัญหาก็ไม่มีทางทำซ้ำได้ สมมติว่าคุณยอมรับหลักฐานขั้นพื้นฐาน


8

แนวทางปฏิบัติของ TDD และ Agile สามารถรับประกันได้ว่าจะสร้างทางออกที่ดีที่สุดได้หรือไม่? (หรือแม้แต่โซลูชันที่ "ดี")

ไม่แน่นอน แต่นั่นไม่ใช่จุดประสงค์ของพวกเขา

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

... [TDD] ตรงข้ามกับการพัฒนาซอฟต์แวร์ที่อนุญาตให้เพิ่มซอฟต์แวร์ที่ไม่ได้รับการพิสูจน์ว่าตรงตามข้อกำหนด ... Kent Beck ผู้ซึ่งให้เครดิตว่ามีการพัฒนาหรือ 'ค้นพบใหม่' เทคนิคระบุไว้ในปี 2003 ว่าTDD ส่งเสริมให้ง่าย การออกแบบและสร้างแรงบันดาลใจความมั่นใจ ( Wikipedia )

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

สำหรับกระบวนการเปรียว:

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

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

แต่นั่นก็โอเคเพราะคำถามนั้นผิด

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

อย่างน้อยที่สุดวิธีปฏิบัติของ TDD และ Agile ยอมรับความยากลำบากและพยายามปรับให้เหมาะสมสำหรับสองสิ่งที่มีวัตถุประสงค์และสามารถวัดได้: Working v. Not-WorkingและSooner v ภายหลัง

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


สิ่งที่คุณสามารถตีความว่าเป็นความพยายามในการผลิตโซลูชั่นที่ดีที่สุดรวมถึงสิ่งต่าง ๆ เช่น:

ฯลฯ ..

ไม่ว่าแต่ละสิ่งเหล่านั้นจะสร้างทางออกที่ดีที่สุดจริง ๆ หรือไม่ก็เป็นคำถามที่ยอดเยี่ยมที่จะถาม!


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

@Frank คำตอบของฉันมีวัตถุประสงค์เพื่อให้ครอบคลุมทั้งในระดับท้องถิ่นและระดับโลก และคำตอบอย่างใดอย่างหนึ่งคือ "ไม่นั่นไม่ใช่สิ่งที่กลยุทธ์เหล่านี้ออกแบบมา - ออกแบบมาเพื่อปรับปรุง ROI และลดความเสี่ยง" ... หรืออะไรทำนองนั้น และนั่นเป็นส่วนหนึ่งเนื่องจากคำตอบของJörgคือ: "ความเหมาะสม" คือเป้าหมายที่กำลังเคลื่อนที่ ... ข้าจะทำมันต่อไปอีกหนึ่งก้าว ไม่เพียง แต่เป็นเป้าหมายเคลื่อนที่เท่านั้น แต่ยังไม่ได้มีวัตถุประสงค์หรือวัดผลได้ทั้งหมด
svidgen

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

@ FrankPuffer Bah ฉันพยายามอัปเดตคำตอบเพื่อบอกว่าดีกว่า ฉันไม่แน่ใจว่าฉันทำให้ดีขึ้นหรือแย่ลง! ... แต่ฉันต้องออกจาก SE.SE และกลับไปทำงาน
svidgen

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

4

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

ในโลกแห่งความเป็นจริงการทดสอบของคุณโดยทั่วไปจะใช้และตรวจสอบกฎเกณฑ์ทางธุรกิจ:

ตัวอย่างเช่น - หากลูกค้าอายุ 30 ปีที่ไม่ได้สูบบุหรี่กับภรรยาและลูกสองคนประเภทพรีเมี่ยมคือ "x" เป็นต้น

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

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


1
ก่อนอื่นเมื่อฉันอ่านคำตอบของคุณฉันคิดว่า "ใช่นั่นคือประเด็นหลัก" แต่หลังจากคิดทบทวนคำถามอีกครั้งฉันคิดว่ามันไม่จำเป็นต้องเป็นนามธรรมหรือไม่สมจริง หากใครเลือกสถาปัตยกรรมที่ผิดอย่างสมบูรณ์แบบสุ่มสี่สุ่มห้า TDD จะไม่แก้ปัญหานั้นไม่ได้หลังจากทำซ้ำ 1,000 ครั้ง
Doc Brown

@Doc Brown ตกลงก็ไม่ได้แก้ปัญหานั้น แต่มันจะให้ชุดการทดสอบที่ใช้กับสมมติฐานและกฎเกณฑ์ทางธุรกิจทุกประการเพื่อให้คุณสามารถปรับปรุงสถาปัตยกรรมซ้ำได้ สถาปัตยกรรมแย่มากที่ต้องมีการแก้ไขเพื่อแก้ไขนั้นหายากมาก (ฉันหวังว่า) และแม้แต่ในกรณีที่รุนแรงการทดสอบกฎธุรกิจจะเป็นจุดเริ่มต้นที่ดี
mcottle

เมื่อฉันพูดว่า "สถาปัตยกรรมผิด" ฉันมีหลายกรณีที่ต้องทิ้งชุดทดสอบที่มีอยู่ คุณอ่านคำตอบของฉัน?
Doc Brown

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

แน่นอนแม้ว่าจะต้องเขียนซ้ำทุกการทดสอบในภาษาการเขียนโปรแกรมใหม่ แต่ก็ไม่จำเป็นต้องทิ้งทุกอย่างไปอย่างน้อยก็สามารถพอร์ตตรรกะที่มีอยู่ได้ และฉันเห็นด้วยกับคุณ 100% สำหรับโครงการสำคัญในโลกแห่งความเป็นจริงสมมติฐานในคำถามค่อนข้างไม่สมจริง
Doc Brown

3

ฉันไม่คิดว่ามันจะเข้าทาง ทีมส่วนใหญ่ไม่มีใครที่มีความสามารถในการหาทางออกที่ดีที่สุดแม้ว่าคุณจะเขียนมันลงบนไวท์บอร์ด TDD / Agile จะไม่เข้าทาง

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

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

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

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


0

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

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


แต่มันเป็นปฏิกิริยาที่แข็งแกร่งเกินไปหรือไม่ ช่วยได้อย่างแน่นอนในหลาย ๆ กรณีที่การวางแผนล่วงหน้าอย่างเข้มงวดพิสูจน์แล้วว่าไม่สะดวกและมีราคาแพง อย่างไรก็ตามปัญหาซอฟต์แวร์บางอย่างต้องจัดการเป็นปัญหาทางคณิตศาสตร์และมีการออกแบบล่วงหน้า คุณไม่สามารถ TDD ได้ คุณสามารถ TDD UI และการออกแบบโดยรวมของ Photoshop แต่คุณไม่สามารถ TDD อัลกอริทึมของมัน พวกมันไม่ใช่ตัวอย่างเล็ก ๆ น้อย ๆ เช่นการหา "sum" หรือ "double" หรือ "pow" ในตัวอย่าง TDD ทั่วไป [1]) คุณอาจไม่สามารถแซวฟิลเตอร์ภาพใหม่ออกมาจากการเขียนสถานการณ์การทดสอบบางอย่าง; คุณต้องนั่งลงและเขียนและเข้าใจสูตรอย่างแน่นอน
Andres F.

2
[1] อันที่จริงฉันค่อนข้างแน่ใจfibonacciซึ่งฉันเคยเห็นว่าใช้เป็นตัวอย่าง / กวดวิชา TDD เป็นเรื่องโกหกไม่มากก็น้อย ฉันยินดีที่จะเดิมพันว่าไม่มีใคร "ค้นพบ" fibonacci หรือซีรี่ส์ที่คล้ายคลึงกันโดย TDD'ing มัน ทุกคนเริ่มจากรู้แล้วว่าฟีโบนัชชีซึ่งกำลังโกง หากคุณพยายามที่จะค้นพบสิ่งนี้โดย TDD'ing มันคุณอาจจะถึงจุดจบของ OP ที่ถูกถามถึง: คุณจะไม่สามารถสรุปชุดข้อมูลโดยการเขียนการทดสอบและการปรับโครงสร้างใหม่มากขึ้น - คุณต้องใช้คณิตศาสตร์ เหตุผล!
Andres F.

ข้อสังเกตสองข้อ: (1) คุณถูกต้องที่สามารถหลอกลวงได้ แต่ฉันไม่ได้เขียนว่า TDD เหมือนกับการเพิ่มประสิทธิภาพทางคณิตศาสตร์ ฉันเพิ่งใช้มันเป็นแบบเปรียบเทียบหรือแบบจำลอง ฉันเชื่อว่าคณิตศาสตร์สามารถ (และควร) นำไปใช้กับเกือบทุกอย่างตราบใดที่คุณตระหนักถึงความแตกต่างระหว่างแบบจำลองและของจริง (2) วิทยาศาสตร์ (งานทางวิทยาศาสตร์) มักคาดการณ์ได้น้อยกว่าการพัฒนาซอฟต์แวร์ และฉันยังบอกด้วยว่าวิศวกรรมซอฟต์แวร์นั้นเป็นเหมือนงานวิทยาศาสตร์มากกว่างานฝีมือ งานฝีมือมักจะต้องทำงานประจำมากขึ้น
Frank Puffer

@AndresF: TDD ไม่ได้หมายความว่าคุณไม่ต้องคิดหรือออกแบบ หมายถึงคุณเขียนการทดสอบก่อนที่จะเขียนการใช้งาน คุณสามารถทำได้ด้วยอัลกอริธึม
JacquesB

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