การเพิ่มการทดสอบหน่วยมีเหตุผลสำหรับรหัสดั้งเดิมที่รู้จักกันดีหรือไม่


21
  • ฉันกำลังพูดถึงการทดสอบหน่วยในความหมาย TDD (ไม่ใช่ "การรวม" โดยอัตโนมัติหรือสิ่งที่คุณต้องการเรียกว่าการทดสอบ)
  • รหัสดั้งเดิมในรหัส (C ++) โดยไม่มีการทดสอบ (ดู: Michael Feathers ' ทำงานอย่างมีประสิทธิภาพด้วยรหัสดั้งเดิม )
  • แต่ยังเป็นรหัสดั้งเดิมใน: รหัสที่ทีมของเราทำงานด้วยกันมา 10-5 ปีที่ผ่านมาดังนั้นเราจึงมักจะมีความคิดที่ดีเกี่ยวกับสถานที่ที่จะนำสิ่งต่าง ๆ มาเปลี่ยนอะไรบางอย่าง
  • เรามีการทดสอบหน่วยในสถานที่ (ผ่าน Boost.Test) สำหรับบางโมดูลที่มาในภายหลังหรือเป็นแบบ "ธรรมชาติ" สำหรับการทดสอบหน่วย (เช่นคอนเทนเนอร์เฉพาะแอปทั่วไปสตริงสิ่งผู้ช่วยเครือข่าย ฯลฯ )
  • เรายังไม่มีการทดสอบการยอมรับอัตโนมัติที่เหมาะสม

ตอนนี้เมื่อเร็ว ๆ นี้ฉันมี "ความสุข" ที่จะใช้คุณสมบัติใหม่ 3 อย่างที่ผู้ใช้งานต้องเผชิญ

แต่ละคนใช้เวลาประมาณ 1-2 ชั่วโมงในการเร่งความเร็วด้วยส่วนรหัสที่ฉันต้องการเปลี่ยน 1-2 ชั่วโมงชั่วโมงในการใช้รหัส (เล็กน้อย) ที่ฉันต้องเปลี่ยนและอีก 1-2 ชั่วโมงเพื่อให้แน่ใจว่าแอป วิ่งอย่างถูกต้องในภายหลังและมันก็ควรจะทำ

ตอนนี้ฉันเพิ่มรหัสเล็กน้อย (ฉันคิดว่าวิธีหนึ่งและสองสามบรรทัดสำหรับแต่ละคุณสมบัติ)

แฟออกรหัสนี้ (ผ่านวิธีการใด ๆ ที่แนะนำในWEwLC ) เพื่อให้การทดสอบหน่วยจะได้ทำให้ความรู้สึก (และไม่ได้รับการพูดซ้ำซากเสร็จสมบูรณ์) จะได้อย่างง่ายดายนำอีก 2-4 ชั่วโมงถ้าไม่มาก สิ่งนี้จะเพิ่มเวลา 50% -100% ให้กับแต่ละคุณสมบัติโดยไม่ได้รับประโยชน์ทันทีเช่น

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

ได้รับถ้า "ใครบางคน" เข้ามาและแตะรหัสนั้นในทางทฤษฎีเขาอาจได้รับประโยชน์จากการทดสอบหน่วยนั้น (ในทางทฤษฎีเท่านั้นเนื่องจากเกาะของรหัสที่ทดสอบนั้นจะอาศัยอยู่ในมหาสมุทรของรหัสที่ยังไม่ผ่านการทดสอบ)

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

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


จะเกิดอะไรขึ้นถ้าแผนกอื่น ๆ จะรับช่วง "รหัสมรดกที่รู้จักกันดี" ของคุณ? พวกนั้นจะทำอะไรกับมัน?
Alex Theodoridis

คำตอบ:


18

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

ฉันจะโต้เถียงกับรหัสใหม่เสมอแต่ในรหัสดั้งเดิมคุณต้องทำการเรียกการตัดสิน

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

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


รหัสที่ดีคืออะไร ที่ได้รับการออกแบบทดสอบทดสอบเอกสารและหลักฐานในอนาคตหรือที่คุณได้รับเงิน และเช่นเคย: คุณสามารถมีได้ดี ; คุณสามารถมีได้ราคาถูก ; คุณสามารถมีได้อย่างรวดเร็ว เลือกสองอันอันที่สามคือต้นทุนของคุณ
Sardathrion - Reinstate Monica

2
"ฉันจะเถียงรหัสใหม่เสมอ" ... "รหัสใหม่" ใน codebase แบบเก่าหรือ "รหัสใหม่ใหม่"? :-)
Martin Ba

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

10

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

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

หากคุณต้องการให้โครงการของคุณอยู่รอดคุณต้องเตรียมมันให้พร้อมสำหรับการเปลี่ยนแปลง


3

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

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


1
แต่ แต่! :-) นั่นควรแปลว่าเป็นการเพิ่มเวลา 100% เพื่อใช้งานฟีเจอร์ใหม่ มันไม่ได้ลดเวลาที่จำเป็นในการใช้คุณสมบัติที่ตามมา มันอาจจะลดเวลาที่จำเป็นเมื่อมีการเปลี่ยนแปลงสิ่งที่
Martin Ba

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

1
@Martin เพราะเห็นได้ชัดว่าคุณทำอะไรคือรหัสสิ่งที่คุณคิดว่าคุณสมบัติควรจะเป็นแล้วส่งมัน ไม่มีการทดสอบใด ๆ เลย ... ไม่ต้องรอ ในฐานะนักพัฒนาเราทุกคนทดสอบโค้ดของเรา (อย่างน้อยด้วยมือ) ก่อนที่จะบอกว่ามันเสร็จสิ้นแล้ว การแทนที่ "ด้วยมือ" ด้วย "โดยการเขียนการทดสอบอัตโนมัติ" ไม่ใช่การเพิ่มเวลา 100% บ่อยครั้งฉันพบว่ามันเกี่ยวกับเวลาเดียวกัน
Kaz Dragon

1
@Kaz - "การแทนที่" ด้วยมือ "กับ" โดยการเขียนการทดสอบอัตโนมัติ "ไม่ใช่เวลาเพิ่มขึ้น 100% บ่อยครั้งฉันพบว่าใช้เวลาประมาณเดียวกัน" - YMMV แต่สำหรับ codebase ของฉันนี่เป็นสิ่งที่ผิดอย่างชัดเจน (ตามที่กำหนดไว้ในคำถาม)
Martin Ba

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

2

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

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

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


1

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

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

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

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

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


"และจัดทำเอกสารการทดสอบของคุณอีกครั้ง - คุณทำเช่นนั้นใช่ไหม?" - {ใส่หมวกเหยียดหยามบน:} ไม่แน่นอน เราไม่ได้อยู่ในดินแดนผู้พัฒนา สิ่งต่างๆจะถูกนำไปใช้และทดสอบและส่งมอบ หลังจากนั้นมันก็จะแตกหักและได้รับการแก้ไขและทดสอบและส่ง
Martin Ba

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

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

0

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

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

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


1
"หากไม่มีการทดสอบหน่วยคุณไม่มีวิธีการอื่นเพื่อให้แน่ใจว่าฟีเจอร์ของคุณจะไม่เสียหายโดยไม่ตั้งใจแม้ว่าจะไม่ได้เปลี่ยนฟีเจอร์นั้นก็ตาม" - การทดสอบหน่วยจะไม่ช่วย เพื่อให้แน่ใจจริงๆฉันจะต้องมีการทดสอบการรวม / การยอมรับอัตโนมัติ
Martin Ba

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