มีหลักการวิศวกรรมซอฟต์แวร์ที่เกี่ยวข้องกับการใช้ซ้ำและการทดสอบการถดถอยในระบบการผลิตหรือไม่?


12

ฉันทำงานกับระบบธุรกรรมทางการเงินขนาดใหญ่สำหรับธนาคารที่ดูแลเงินบำนาญและการลงทุน หลังจากการเปลี่ยนแปลงคุณสมบัติ 15 ปีค่าใช้จ่ายในการทดสอบการถดถอยแบบแมนนวลก็เพิ่มขึ้นเป็น $ 200K ต่อการเปิดตัว (10M LOC ทำธุรกรรม $ 10M ต่อวัน) ระบบนี้ยังเชื่อมต่อกับ 19 ระบบอื่น ๆ ทั่ว บริษัท ที่ย้ายข้อมูลจำนวนมาก ระบบนี้ถูกนำไปใช้ใน Java

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

คำถามของฉันคือมีหลักการวิศวกรรมซอฟต์แวร์ที่อธิบายความสัมพันธ์ระหว่างต้นทุนการทดสอบซ้ำและการถดถอยซ้ำหรือไม่

เหตุผลที่ฉันถามคำถามนี้คือเนื้อหามีประโยชน์ต้นทุนในการย่อยสลายระบบเป็นส่วนเล็ก ๆ ที่จะทดสอบ

สมมติฐาน:

  1. 'การทดสอบการถดถอย' หมายถึง 'การทดสอบการยอมรับ' - นั่นคืออีกกลุ่มใช้เวลาในการเขียนการทดสอบแบบเก่าและนำมาใช้ซ้ำกับระบบในนามของธุรกิจรวมถึงการตั้งค่าสภาพแวดล้อมและข้อมูล

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

    (a) การทดสอบอัตโนมัติมีประโยชน์น้อยกว่าขอบเขตของระบบเว้นแต่ว่าระบบนั้นจะมีการครอบคลุมการทดสอบอัตโนมัติสูงเช่นกัน (ทรงกลมท้าทายอิทธิพล)

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

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

    (d) นี่เป็นเพียงความเป็นจริงทางวัฒนธรรมของการทำงานในธนาคาร

    (e) ฉันกำลังทำงานเพื่อแก้ไขปัญหานี้ในวิธีที่แตกต่าง (การสลายตัว)


2
คุณสร้างคำแถลงด้วยมือที่“ เราสังเกต […] ว่ายิ่งเรา 'นำมาใช้ซ้ำ' มากเท่าไหร่ค่าใช้จ่ายในการทดสอบ [การยอมรับมากขึ้นก็จะมากขึ้น ” - คุณขยายได้ไหม? ไม่ควรมีการทดสอบการยอมรับที่ไม่เชื่อเรื่องรายละเอียดของการใช้งานเช่นลำดับชั้นการสืบทอดและแทนที่จะเล่นผ่านสถานการณ์การใช้งานเช่น
amon

2
คำถามของคุณน่าสนใจ แต่มีข้อสมมติฐานที่เอนเอียงมากเช่น "การใช้ซ้ำเป็นผลมาจาก OO" หรือส่วนที่ @amon กล่าวถึง ฉันขอแนะนำให้คุณลบส่วน "OO" ออกทั้งหมดเนื่องจากคำถามหลักของคุณไม่ขึ้นอยู่กับภาษาการเขียนโปรแกรมหรือการเขียนโปรแกรม OO ใด ๆ และมันก็ไม่มีความชัดเจนว่า "การนำกลับมาใช้ใหม่" แบบไหนที่คุณนึกไว้ - "นำมาใช้ใหม่" เป็นคำที่กว้างการใช้ซ้ำคัดลอกวางแตกต่างจากส่วนประกอบหรือไลบรารีที่นำมาใช้ซ้ำ
Doc Brown

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

1
ในรูปแบบปัจจุบันฉันเดาว่าฉันจะตอบเพียง "ไม่ฉันไม่คิดอย่างนั้น" กับคำถามของคุณ - ซึ่งฉันคิดว่าคงไม่เป็นที่น่าพอใจสำหรับคุณ หรือคุณสนใจในหลักการและแนวทางปฏิบัติเพื่อลดค่าใช้จ่ายในการทดสอบจริง ๆ เมื่อสร้างระบบขนาดใหญ่เช่นคุณด้วยส่วนประกอบที่สามารถนำกลับมาใช้ใหม่ได้เอง?
Doc Brown

คำตอบ:


11

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

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

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

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

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

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


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

การ จำกัด เพียงสองตัวเลือกนี้ไม่จำเป็นและอีกครั้งคุณสามารถหาตัวอย่างของวิธีการทำได้ดีขึ้นใน JDK ที่คุณใช้ ดูjava.util.concurrentแพ็คเกจ ( JSR 166 ) - จนกว่า Java 5 รีลีสจะเป็นไลบรารี่ที่แยกต่างหากไม่ใช่ส่วนหนึ่งของคอร์ JDK หลัก

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

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

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


ตัวอย่างที่ชัดเจนของความพยายาม (รวมถึงการทดสอบ) ที่อาจเกี่ยวข้องกับการเปลี่ยนรหัสที่ใช้ซ้ำอย่างหนักสามารถพบได้อีกครั้งใน JDK ในรีลีส 7u6 พวกเขาเปลี่ยนการStringเป็นตัวแทนภายในที่เกี่ยวข้องกับการเปลี่ยนแปลงsubstringประสิทธิภาพ ความคิดเห็นของนักพัฒนาคุณลักษณะที่ Reddit แสดงให้เห็นถึงความพยายามในการเปลี่ยนแปลงนี้:

การวิเคราะห์เบื้องต้นมาจากกลุ่ม GC ในปี 2007 ...

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

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


ดูเหมือนว่าเราทั้งสองทำงานอยู่กับคำตอบในแบบคู่ขนานที่มีจำนวนมากของความคิดที่คล้ายกัน ...
หมอสีน้ำตาล

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

9

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

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

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

  • ส่วนประกอบเหล่านั้นมีความสมบูรณ์และเสถียรมาก

  • พวกเขาได้รับการพัฒนาและทดสอบแยกอย่างสมบูรณ์โดยองค์กรที่แตกต่างกันโดยสิ้นเชิง

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

  • คุณไม่ได้รับเวอร์ชันใหม่ทุกวันเฉพาะการปรับปรุงเล็กน้อย (สูงสุดต่อเดือน) หรือการอัปเดตที่สำคัญในช่วงเวลาต่อปี

  • การอัปเดตส่วนใหญ่ได้รับการออกแบบให้ใช้งานร่วมกันได้ 100% โดยเฉพาะการอัปเดตเล็กน้อย

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

  • สำหรับส่วนประกอบที่นำกลับมาใช้ใหม่ได้มีความรับผิดชอบที่ชัดเจนซึ่งทำการบำรุงรักษาและตรวจสอบให้แน่ใจว่าทุกคนที่นำส่วนประกอบนั้นมาใช้ใหม่จะสามารถรับข้อผิดพลาดได้ทันทีหากเกิดปัญหาขึ้น

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

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

  • ส่วนประกอบที่นำมาใช้ซ้ำต้องมีชุดการทดสอบที่สมบูรณ์มากเพื่อทดสอบแยก

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


0

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

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

โดยง่ายฉันหมายถึงพวกเขาควรใช้เวลาน้อยลงและทำให้ค่าใช้จ่ายน้อยลง

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

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

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

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

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

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