TDD ใช้งานได้จริงสำหรับโครงการที่ซับซ้อนหรือไม่?


53

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

  • การสร้างและรักษาข้อมูลจำลอง

มันยากและไม่สมจริงในการรักษาข้อมูลจำลองขนาดใหญ่ มันยิ่งยากขึ้นเมื่อโครงสร้างฐานข้อมูลผ่านการเปลี่ยนแปลง

  • ทดสอบ GUI

แม้จะมี MVVM และความสามารถในการทดสอบ GUI แต่ก็ต้องใช้รหัสจำนวนมากเพื่อจำลองสถานการณ์ GUI

  • ทดสอบธุรกิจ

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

  • ความขัดแย้งในข้อกำหนด

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

ฉันได้อ่านคำถามนี้: เหตุใด TDD จึงทำงานได้

TDD ใช้งานได้จริงสำหรับโครงการขององค์กรที่ซับซ้อนหรือ จำกัด ประเภทโครงการหรือไม่


+1 ฉันมีคำถามเดียวกันหลังจากอ่านคำถามนั้น - ฉันใช้อย่าง จำกัด ด้วยปัญหาเดียวกันกับข้อมูลจำลอง
Michael K

20
"TDD ต้องการให้ข้อกำหนดนั้นถูกต้อง 100%" โดยที่ "ข้อกำหนด" หมายถึง "ฉันต้องรู้ว่าวิธีการเดียวนี้ต้องใช้งานอย่างไร" และถ้าคุณไม่รู้ว่าวิธีการนั้นควรใช้งานอย่างไรคุณควรจะใช้มันอย่างไร?
Frank Shearar

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

7
ฉันจะบอกว่า TDD เป็นสิ่งเดียวที่ใช้ได้กับโครงการขนาดใหญ่! โครงการที่มีขนาดใหญ่ก็จะมีการโต้ตอบและความต้องการที่ซับซ้อนมากขึ้นการเปลี่ยนแปลงแบบสุ่ม - TDD เท่านั้นที่สามารถติดตามได้
Martin Beckett

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

คำตอบ:


53

มันยากและไม่สมจริงในการรักษาข้อมูลจำลองขนาดใหญ่ มันยิ่งยากขึ้นเมื่อโครงสร้างฐานข้อมูลผ่านการเปลี่ยนแปลง

เท็จ

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

นอกจากนี้โปรแกรมเมอร์ที่ขี้เกียจอย่างแท้จริงขอให้ผู้เชี่ยวชาญในประเด็นการสร้างสเปรดชีตที่เรียบง่ายของกรณีทดสอบต่างๆ เพียงแค่สเปรดชีตที่เรียบง่าย

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

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

แม้จะมี MVVM และความสามารถในการทดสอบ GUI แต่ก็ต้องใช้รหัสจำนวนมากเพื่อจำลองสถานการณ์ GUI

อะไร? "ทบทวน"?

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

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

นั่นเป็นเรื่องจริง

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

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

และ. ฉันต้องเขียนกรณีทดสอบด้วยตนเองเพราะสเปรดชีตไม่สมบูรณ์

อย่างไรก็ตาม เมื่อผู้ใช้รายงานว่า "บั๊ก" ฉันเพียงแค่ถามว่ากรณีทดสอบใดในสเปรดชีตผิด

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

แทนที่จะฟังผู้เชี่ยวชาญพยายามอธิบายกระบวนการทางธุรกิจที่ซับซ้อนเป็นพิเศษผู้เชี่ยวชาญต้องสร้างตัวอย่างที่เป็นรูปธรรมของกระบวนการ

TDD ต้องการให้ข้อกำหนดนั้นถูกต้อง 100% ในกรณีเช่นนี้อาจคาดได้ว่าความต้องการที่ขัดแย้งกันนั้นจะเกิดขึ้นระหว่างการสร้างการทดสอบ แต่ปัญหาคือว่านี่ไม่ใช่กรณีในสถานการณ์ที่ซับซ้อน

ไม่ได้ใช้ TDD อย่างแน่นอนว่าข้อกำหนดนั้นถูกต้อง 100% บางคนอ้างว่า TDD สามารถทนต่อข้อกำหนดที่ไม่สมบูรณ์และเปลี่ยนแปลงได้ซึ่งวิธีการที่ไม่ใช่ TDD ไม่สามารถทำงานกับข้อกำหนดที่ไม่สมบูรณ์ได้

หากคุณไม่ได้ใช้ TDD ความขัดแย้งจะพบได้ในช่วงดำเนินการ

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

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


4
@ S.Lott เนื่องจาก OP น่าจะพูดถึง WPF / SL เกี่ยวกับ MVVM มากที่สุดความคิดเห็นในการทดสอบ GUI ของคุณนั้นค่อนข้างไม่ดี แม้ว่าจะมีการแยกตัวและวิธีการ MVVM ที่เข้มงวด แต่การดูจากคำจำกัดความยังคงยุ่งยากในการทดสอบ นี่คือกับ UI ใด ๆ การทดสอบมุมมองนั้นใช้เวลานานมีความยุ่งยากและ ROI ต่ำ นี่คือจุดที่ข้อโต้แย้งเกี่ยวกับพื้นผิว MVVM ที่ทดสอบ M / VM และการเพิกเฉยต่อ V อาจเป็นวิธีที่ดีที่สุดอย่างไรก็ตามการทดสอบส่วนประกอบในมุมมองเช่นการวางตำแหน่งของการควบคุมการระบายสี ฯลฯ ... ยังคงใช้เวลานานและ ซับซ้อน
Aaron McIver

3
@ S.Lott ขึ้นอยู่กับขอบเขต TDD ไม่ได้ให้คุณค่าอย่างมากเกี่ยวกับการทดสอบมุมมอง อย่างไรก็ตาม TDD ให้คุณค่าอย่างมากเกี่ยวกับการทดสอบ Model และ ViewModel หากขอบเขตของคุณคือ ViewModel และ View ค่าของ TDD จะแตกต่างกันมากตามขอบเขตของคุณถ้าขอบเขตของคุณคือ Model และบริการที่ต้องการ อย่าเข้าใจฉันผิดฉันเชื่อว่า TDD มีมูลค่าอย่างมากในโครงการที่ซับซ้อน ... ค่าของมันแตกต่างกันตามขอบเขต
Aaron McIver

5
@ Robert Harvey: มันเป็นสิ่งประดิษฐ์ของฉันไม่ได้ ฉันขี้เกียจเกินไปที่จะประดิษฐ์อะไร
S.Lott

4
@Amir Rezaei: ฉันขอโทษที่ข้อมูลการทดสอบหน่วยขั้นต่ำของคุณซับซ้อน มันไม่มีส่วนเกี่ยวข้องกับ TDD ใบสมัครของคุณซับซ้อน คุณยังต้องทดสอบใช่ไหม คุณยังต้องสร้างข้อมูลทดสอบหรือไม่ หากคุณไม่ได้ติดตาม TDD คุณจะสร้างแอปพลิเคชันที่ทดสอบได้อย่างไร โชค? หวัง? ใช่. มันซับซ้อน ไม่มีสิ่งใดขจัดความซับซ้อน TDD รับรองว่าคุณจะต้องทดสอบความซับซ้อนนั้น
S.Lott

4
@ Amir Rezaei: "เรากำลังออกแบบเพื่อความเป็นจริง" คุณจะเขียนแบบทดสอบหรือไม่? ถ้าเป็นเช่นนั้นออกแบบสำหรับการทดสอบ หากคุณจะไม่เขียนข้อสอบคุณจะรู้ได้อย่างไรว่ามีอะไรบ้าง?
S.Lott

28

ใช่

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

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

ไม่ต้องสงสัยเลยว่าอย่างน้อยก็ในส่วนของ TDD และยืนยันว่าการทดสอบทุกหน่วยผ่านเสมอการปล่อยรุ่น 1.0 มาก่อนภายใต้งบประมาณและมีความเสถียรอย่างน่าอัศจรรย์

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


8
removed the requirement that unit tests pass. It was astonishing how quickly quality went down the toilet, and then the schedule followed it.- เหมือนกับบอกคนขับรถ F1 ของคุณว่าเขาไม่ได้รับอนุญาต Pit Stops เพราะใช้เวลามากเกินไป ... Idiotic
Jess Telford

1
นี่เป็นตัวอย่างสิ่งที่ฉันพูด: วิธีเดียวที่จะไปเร็วคือไปได้ดี !
TheCatWhisperer

18

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

a) คุณได้รับการตรวจสอบการออกแบบของคุณเร็วขึ้นมากเนื่องจากวงข้อเสนอแนะของคุณแน่นมากขึ้นเนื่องจากการทดสอบจากการไป

b) คุณสามารถเปลี่ยนบิตและชิ้นส่วนและดูว่าระบบตอบสนองอย่างไรเนื่องจากคุณได้สร้างการครอบคลุมการทดสอบตลอดเวลา

c) รหัสที่เสร็จแล้วจะดีขึ้นมากเป็นผล


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

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

10

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

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

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

การทดสอบธุรกิจ
ไม่พบว่ามีปัญหา การทดสอบขนาดเล็กจำนวนมาก ดังที่ฉันได้กล่าวไว้ข้างต้นบางกรณี (ตัวแก้ปริศนา Sudoku เป็นที่นิยม) เห็นได้ชัดว่าเป็นการยากที่จะทำ TDD

TDD ต้องการให้ข้อกำหนดนั้นถูกต้อง 100%
ไม่มีไม่ได้ คุณได้แนวคิดนี้มาจากไหน การปฏิบัติแบบเปรียวทั้งหมดยอมรับว่าความต้องการนั้นเปลี่ยนไป คุณจำเป็นต้องรู้ว่าคุณกำลังทำอะไรอยู่ก่อนที่จะทำ แต่สิ่งนี้ไม่เหมือนกับที่กำหนดให้เป็น 100% TDD เป็นวิธีปฏิบัติทั่วไปในการต่อสู้ที่ความต้องการ (User Stories) นั้นโดยนิยามแล้วไม่สมบูรณ์ 100%


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

"หน่วย" มีขนาดเล็กกว่าข้อกำหนดและโดยทั่วไปสามารถทำได้โดยไม่ต้องผูก UAC ทั้งหมดไว้
mlk

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

9

ก่อนอื่นฉันเชื่อว่าปัญหาของคุณเกี่ยวกับการทดสอบหน่วยโดยทั่วไปมากกว่า TDD เนื่องจากฉันไม่เห็นอะไรเลยที่เฉพาะเจาะจงกับ TDD (วงจรการทดสอบครั้งแรก + แดง - เขียว - refactor) ในสิ่งที่คุณพูด

มันยากและไม่สมจริงในการรักษาข้อมูลจำลองขนาดใหญ่

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

มันยิ่งยากขึ้นเมื่อโครงสร้างฐานข้อมูลผ่านการเปลี่ยนแปลง

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

แม้จะมี MVVM และความสามารถในการทดสอบ GUI แต่ก็ต้องใช้รหัสจำนวนมากเพื่อจำลองสถานการณ์ GUI

คุณถูกต้องการทดสอบหน่วย GUI (มุมมอง) ไม่ใช่เรื่องง่ายและหลายคนกำลังทำได้ดีหากไม่มี (นอกเหนือจากนี้การทดสอบ GUI ไม่ได้เป็นส่วนหนึ่งของ TDD) ในทางตรงกันข้ามหน่วยทดสอบ Controller / Presenter / ViewModel ของคุณ / อะไรก็ตามที่แนะนำให้ใช้เลเยอร์ระดับกลางจริงๆแล้วมันเป็นหนึ่งในเหตุผลหลักที่รูปแบบเช่น MVC หรือ MVVM

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

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

TDD ต้องการให้ข้อกำหนดนั้นถูกต้อง 100%

ไม่ได้อย่างแน่นอน. ซอฟต์แวร์ที่ประสบความสำเร็จต้องการให้ข้อกำหนดนั้นถูกต้อง 100%;) การทดสอบหน่วยเพียงสะท้อนสิ่งที่คุณต้องการในขณะนี้ ถ้าวิสัยทัศน์มีข้อบกพร่องรหัสและซอฟต์แวร์ของคุณก็จะเหมือนกันการทดสอบหน่วยหรือไม่ ... และนั่นคือสิ่งที่การทดสอบหน่วยส่องแสง: ด้วยชื่อเรื่องการทดสอบที่ชัดเจนเพียงพอการตัดสินใจออกแบบและการตีความข้อกำหนดของคุณจะโปร่งใส นิ้วของคุณในสิ่งที่จะต้องเปลี่ยนในครั้งต่อไปที่ลูกค้าของคุณพูดว่า "กฎเกณฑ์ทางธุรกิจนี้ไม่ได้เป็นอย่างที่ฉันต้องการ"


6

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


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

ทางเลือกหนึ่งคือการทดสอบการถดถอย คิดพูดทดสอบเว็บเบราว์เซอร์ สมมติว่าคุณเป็น Google และคุณต้องการทดสอบ Chrome เวอร์ชันใหม่ คุณสามารถทดสอบองค์ประกอบ CSS แต่ละรายการและทุกแอตทริบิวต์ของแท็ก HTML ทุกประเภทและทุกสิ่งพื้นฐานที่ JavaScript สามารถทำได้ แต่มีฟีเจอร์เหล่านี้ที่เป็นไปได้ผสมกันจำนวนเท่าใด? ฉันไม่คิดว่าจะมีใครรู้ ดังนั้นพวกเขาจึงทำการทดสอบคุณสมบัติแต่ละอย่างในสายรัดต่าง ๆ แต่ท้ายที่สุดพวกเขาจะทำการถดถอยกับเว็บไซต์ธนาคารที่รู้จัก นั่นคือลิงล้านตัวตรงนั้น
Dan Korn

ทางเลือกที่เหมือนจริงคือส่งมอบซอฟต์แวร์ที่ใช้งานไม่ได้ ภายใต้สถานการณ์ที่เหมาะสมสิ่งนี้ยังสามารถทำกำไรได้ เลือกตัวอย่างที่คุณชื่นชอบ
soru

4

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


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

"และกรณีที่ซับซ้อนพอเพียงได้ผล & ตรวจสอบโดยผู้เชี่ยวชาญด้านโดเมน" - เป็นการทดสอบหน่วยหรือการทดสอบการถดถอย
quant_dev

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

@quant_dev เป็นการทดสอบหน่วย มันทดสอบพฤติกรรมของหน่วยในชุดข้อมูลการทดสอบที่ซับซ้อนมากขึ้น คุณสามารถใช้การทดสอบหน่วยสำหรับการทดสอบการถดถอย คุณควรเขียนการทดสอบการถดถอยสำหรับข้อบกพร่องที่เกิดขึ้นเพื่อป้องกันการเกิดซ้ำ (มีหลักฐานว่าข้อบกพร่องคลัสเตอร์)
ทิม Williscroft

@dsimcha: ดังนั้นวิธีการทางสถิติในการทดสอบหน่วยอาจใช้งานได้สำหรับคุณเนื่องจากคุณสามารถคาดการณ์โดยประมาณได้ ฉันใช้วิธีการนี้ในระบบอาวุธเพื่อเลือกและแก้ไขข้อบกพร่องของเป้าหมายเคลื่อนที่รหัสการมีส่วนร่วมของนักกีฬา มันยากมากที่จะหาคำตอบสำหรับสิ่งนั้นด้วยมือ แต่ค่อนข้างง่ายที่จะหาคำตอบว่าตัวทำนายนั้นใช้งานได้จริง (คุณแทบจะยิงกระสุนปืนออกมาและดูว่ามันกระทบกับที่ใดบ้างฟองล้างซ้ำ 100000 ครั้ง A ทำงานได้ 91% ของเวลา, AlgorithmB ทำงานได้ 85% ของเวลา)
Tim Williscroft

4
> Does TDD really work for complex projects?

จากประสบการณ์ของฉัน: ใช่สำหรับ Unittests (ทดสอบโมดูล / คุณสมบัติแยก) เพราะสิ่งเหล่านี้ส่วนใหญ่ไม่มีปัญหาที่คุณพูดถึง: (Gui, Mvvm, Business-Modell) ฉันไม่เคยมีมากกว่า 3 mocks / ต้นขั้วที่จะเติมเต็มหนึ่ง unittest (แต่อาจโดเมนของคุณต้องการมากขึ้น)

อย่างไรก็ตามฉันไม่เห็นด้วยถ้า TDD สามารถแก้ไขปัญหาที่คุณกล่าวถึง ในการรวมหรือการทดสอบแบบ end-to-endด้วยการทดสอบแบบ BDD

แต่อย่างน้อยปัญหาบางอย่างก็สามารถลดลงได้

> However complex business logic is hard to test since the number 
> of combinations of tests (test space) is very large.

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

ตัวอย่าง: การตรวจสอบสิทธิ์ผู้ใช้ที่ซับซ้อน

การทดสอบฟังก์ชั่นIsAllowedToEditCusterData()ในระดับการทดสอบการรวมจะต้องถามวัตถุที่แตกต่างกันสำหรับข้อมูลเกี่ยวกับผู้ใช้โดเมนลูกค้าสภาพแวดล้อม ....

การเยาะเย้ยส่วนต่าง ๆ เหล่านี้ค่อนข้างจะเป็นการแพร่กระจาย นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งหากIsAllowedToEditCusterData()ต้องรู้จักวัตถุต่าง ๆ เหล่านี้

ในระดับ Unittest คุณจะมีฟังก์ชั่นIsAllowedToEditCusterData()ที่รับพารามิเตอร์ 20 ตัวอย่างที่มีทุกสิ่งที่จำเป็นต้องรู้ เนื่องจาก IsAllowedToEditCusterData()ไม่จำเป็นต้องรู้ว่าฟิลด์ใด a user, a domain, a customer, .... มีสิ่งนี้ทดสอบได้ง่าย

เมื่อฉันต้องนำไปใช้IsAllowedToEditCusterData()ฉันมีโอเวอร์โหลดสองอัน:

โอเวอร์โหลดหนึ่งตัวที่ไม่ทำอะไรเลยนอกจากรับพารามิเตอร์ 20 ตัวจากนั้นเรียกโอเวอร์โหลดด้วยพารามิเตอร์ 20 ตัวที่ตัดสินใจ

(ของฉันIsAllowedToEditCusterData()มีเพียง 5 พารามิเตอร์และฉันต้องการชุดค่าผสม 32 ชุดเพื่อทดสอบอย่างสมบูรณ์)

ตัวอย่าง

// method used by businesslogic
// difficuilt to test because you have to construct
// many dependant objects for the test
public boolean IsAllowedToEditCusterData() {
    Employee employee = getCurrentEmployee();
    Department employeeDepartment = employee.getDepartment();
    Customer customer = getCustomer();
    Shop shop = customer.getShop();

    // many more objects where the permittions depend on

    return IsAllowedToEditCusterData(
            employee.getAge(),
            employeeDepartment.getName(),
            shop.getName(),
            ...
        );
}

// method used by junittests
// much more easy to test because only primitives
// and no internal state is needed
public static boolean IsAllowedToEditCusterData(
        int employeeAge,
        String employeeDepartmentName,
        String shopName,
        ... ) 
{
    boolean isAllowed; 
    // logic goes here

    return isAllowed;
}

1
+1 ตัวอย่างที่ดีมาก“ การตรวจสอบสิทธิ์ผู้ใช้ที่ซับซ้อน” ซึ่งเป็นหนึ่งในสถานการณ์จำลองของเรา
Amir Rezaei

3

คำตอบที่น่าเศร้าก็คือไม่มีอะไรเหมาะกับโครงการขนาดใหญ่!

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


1

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

"Wtf ทำไมรหัสสาขานี้ถึงอยู่ที่นั่นไม่รู้อาจจะมีบางคนต้องการมันทิ้งไว้ที่นั่นดีกว่าจะทำให้ใคร ๆ รู้สึกไม่ดี ... " เมื่อเวลาผ่านไปโครงการที่ซับซ้อนกลายเป็นที่ทิ้งขยะ

ด้วยการทดสอบทุกคนสามารถพูดได้อย่างมั่นใจว่า "ฉันได้ทำการเปลี่ยนแปลงครั้งใหญ่ แต่การทดสอบทั้งหมดยังคงผ่านไป" ตามคำนิยามเขาไม่ได้หักอะไรเลย สิ่งนี้นำไปสู่โครงการความคล่องตัวที่สามารถพัฒนาได้มากขึ้น อาจเป็นหนึ่งในเหตุผลที่เรายังต้องการคนรักษา COBOL เพราะการทดสอบไม่เป็นที่นิยมตั้งแต่: P


1

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

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

ดังนั้นความสมดุลคือกุญแจสำคัญ TDD อาจจะดี แต่อย่าพึ่งใช้มันโดยเฉพาะ


1
TDD ไม่ได้ป้องกันความโง่เขลา TDD เป็นส่วนหนึ่งของความคล่องตัว แต่สิ่งสำคัญอีกอย่างหนึ่งก็คือการส่งมอบโค้ดที่รันได้และรันได้ในแต่ละ sprint ...
oligofren

0

ฉันคิดอย่างนั้นดูการพัฒนาขับเคลื่อนทดสอบ

ในปี 2008 Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat และ Laurie Williams เขียนบทความที่เรียกว่า"การปรับปรุงคุณภาพให้ดีขึ้นผ่านการพัฒนาแบบทดสอบ: ผลลัพธ์และประสบการณ์ของสี่ทีมอุตสาหกรรม" (ลิงค์ PDF) นามธรรม:

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

ในปี 2012 แนวทางการพัฒนาของ Ruby on Rails ถือว่าเป็น TDD ฉันเองพึ่งพาเครื่องมือเช่น rspec สำหรับการเขียนการทดสอบและ mocks, factory_girl สำหรับการสร้างวัตถุ, capybara สำหรับการทำงานอัตโนมัติของเบราว์เซอร์, simplecov สำหรับการครอบคลุมโค้ดและการป้องกันสำหรับการทดสอบอัตโนมัติเหล่านี้

อันเป็นผลมาจากการใช้วิธีการนี้และเครื่องมือเหล่านี้ฉันมักจะเห็นด้วยกับใจ Nagappan et al ...


0

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

บางทีความต้องการมีความซับซ้อนและผันผวนโครงสร้างพื้นฐานไม่แน่นอนทีมรองและมีการหมุนเวียนสูงหรือสถาปนิกเป็นคนงี่เง่า

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

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


-1

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

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