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


72

ผมมักจะพยายามที่จะทำตามคำแนะนำของหนังสือเล่มนี้ทำงานอย่างมีประสิทธิภาพกับมรดกค้อ ฉันทำลายการพึ่งพาย้ายส่วนต่าง ๆ ของรหัสไปยัง@VisibleForTesting public staticวิธีการและไปยังคลาสใหม่เพื่อให้รหัส (หรืออย่างน้อยก็บางส่วนของมัน) ทดสอบได้ และฉันเขียนการทดสอบเพื่อให้แน่ใจว่าฉันจะไม่ทำลายสิ่งใดเมื่อฉันแก้ไขหรือเพิ่มฟังก์ชั่นใหม่

เพื่อนร่วมงานคนหนึ่งบอกว่าฉันไม่ควรทำเช่นนี้ เหตุผลของเขา:

  • รหัสต้นฉบับอาจทำงานไม่ถูกต้องตั้งแต่แรก และการเขียนการทดสอบทำให้การแก้ไขและการแก้ไขในอนาคตยากขึ้นเนื่องจาก devs ต้องเข้าใจและแก้ไขการทดสอบด้วย
  • หากเป็นโค้ด GUI ที่มีตรรกะ (ตัวอย่างเช่น ~ 12 บรรทัด, 2-3 if / else บล็อก) การทดสอบจะไม่คุ้มกับปัญหาเนื่องจากรหัสนั้นเล็กน้อยเกินไปที่จะเริ่มต้น
  • รูปแบบที่ไม่ดีที่คล้ายกันอาจมีอยู่ในส่วนอื่น ๆ ของ codebase เช่นกัน (ซึ่งฉันยังไม่ได้เห็นฉันค่อนข้างใหม่); มันจะง่ายกว่าในการทำความสะอาดพวกเขาทั้งหมดใน refactoring ใหญ่ การแยกตรรกะออกอาจทำให้ความเป็นไปได้ในอนาคตลดลง

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


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

3
สิ่งที่ควรจะจัดว่าเป็นข้อผิดพลาดที่อาจจะอาศัยโดยส่วนอื่น ๆ ของรหัสที่เปลี่ยนมันเป็นคุณลักษณะ
วงล้อประหลาด

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

6
ประเด็นแรกคือเฮฮา -“ อย่าทดสอบนะมันอาจจะบั๊ก” อืมใช่มั้ย ถ้าอย่างนั้นเราก็ควรที่จะรู้ว่า - เราต้องการที่จะแก้ไขปัญหานั้นหรือไม่ต้องการให้ใครเปลี่ยนพฤติกรรมที่แท้จริงไปเป็นสิ่งที่นักออกแบบบางคนบอก ไม่ว่าจะด้วยวิธีใดการทดสอบ (และการรันการทดสอบในระบบอัตโนมัติ) จะเป็นประโยชน์
Christopher Creutzig

3
บ่อยครั้งที่ "การปรับโครงสร้างครั้งใหญ่ครั้งหนึ่ง" ที่กำลังจะเกิดขึ้นและนั่นจะช่วยรักษาความเจ็บป่วยทั้งหมดได้เป็นตำนานโดยผู้ที่ต้องการผลักดันสิ่งที่พวกเขาคิดว่าน่าเบื่อ (การทดสอบการเขียน) ในอนาคตอันห่างไกล และถ้ามันกลายเป็นจริงพวกเขาจะเสียใจอย่างจริงจังหากปล่อยให้มันใหญ่มาก!
Julia Hayward

คำตอบ:


100

นี่คือความประทับใจตามหลักวิทยาศาสตร์ส่วนตัวของฉัน: ทั้งสามเหตุผลฟังดูเหมือนภาพลวงตาทางปัญญาที่แพร่หลาย แต่ไม่จริง

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

23
+1 สำหรับ "ข้อผิดพลาดที่ร้ายแรงทั้งหมดได้ถูกกำหนดไว้เพราะผู้คนคิดว่าพวกเขาเข้าใจบางสิ่งที่ดีกว่าที่ทำจริง"
rem

เรื่องจุด 1 - กับBDDการทดสอบที่มีการจัดเก็บเอกสารด้วยตนเอง ...
ร็อบบี้ดี

2
ตามที่ @ guillaume31 ชี้ให้เห็นส่วนหนึ่งของค่าของการทดสอบการเขียนแสดงให้เห็นว่ารหัสใช้งานได้จริง - ซึ่งอาจหรืออาจจะไม่เป็นไปตามข้อกำหนด แต่มันอาจเป็นสเป็คที่ "ผิด": ความต้องการทางธุรกิจอาจมีการเปลี่ยนแปลงและรหัสนี้สะท้อนถึงข้อกำหนดใหม่ แต่สเป็คไม่ได้ เพียงสมมติว่ารหัสคือ "ผิด" นั้นง่ายเกินไป (ดูจุดที่ 1) และการทดสอบอีกครั้งจะบอกคุณว่ารหัสทำอะไรได้จริงไม่ใช่สิ่งที่ใครบางคนคิด / บอกว่าทำ (ดูจุดที่ 2)
David

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

50

ความคิดเล็กน้อย:

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

ฉันยอมรับว่ารหัส GUI บริสุทธิ์นั้นยากที่จะทดสอบและอาจไม่เหมาะสำหรับ " การทำงานอย่างมีประสิทธิภาพ ... " - การปรับรูปแบบใหม่ อย่างไรก็ตามนี่ไม่ได้หมายความว่าคุณไม่ควรแยกพฤติกรรมที่ไม่มีส่วนเกี่ยวข้องในเลเยอร์ GUI และทดสอบรหัสที่แยกออกมา และ "12 บรรทัด, 2-3 ถ้า / บล็อกอื่น" ไม่ได้เป็นเรื่องเล็กน้อย รหัสทั้งหมดที่มีตรรกะอย่างน้อยหนึ่งเงื่อนไขควรได้รับการทดสอบ

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

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


5
+1 สำหรับ "การทดสอบที่คุณเขียนทดสอบพฤติกรรมปัจจุบันของโปรแกรม"
David

17

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


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

14

คำตอบของ Kilian ครอบคลุมประเด็นที่สำคัญที่สุด แต่ฉันต้องการขยายในข้อ 1 และ 3

หากผู้พัฒนาต้องการเปลี่ยนรหัส (refactor, expand, debug) เธอต้องเข้าใจมัน เธอต้องตรวจสอบให้แน่ใจว่าการเปลี่ยนแปลงของเธอส่งผลกระทบต่อพฤติกรรมที่เธอต้องการ (ไม่มีอะไรในกรณีของการปรับโครงสร้าง) และไม่มีอะไรอื่น

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

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

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

  • Antipattern ที่จะทำการเปลี่ยนสภาพจะต้องพบได้ง่าย ซิงเกิลของคุณชื่อXYZSingletonหรือไม่ ผู้เรียกตัวอย่างของพวกเขาถูกเรียกเสมอgetInstance()หรือไม่? และคุณจะพบลำดับชั้นลึก ๆ ของคุณได้อย่างไร คุณจะค้นหาสิ่งที่พระเจ้าของคุณได้อย่างไร สิ่งเหล่านี้จำเป็นต้องมีการวิเคราะห์เมทริกโค้ดจากนั้นทำการตรวจสอบเมทริกด้วยตนเอง หรือคุณเพียงแค่สะดุดพวกเขาในขณะที่คุณทำงานตามที่คุณทำ
  • การปรับโครงสร้างจะต้องเป็นกลไก ในกรณีส่วนใหญ่ส่วนที่ยากของการปรับโครงสร้างใหม่คือการทำความเข้าใจโค้ดที่มีอยู่ดีพอที่จะรู้วิธีการเปลี่ยน Singletons อีกครั้ง: หากซิงเกิลหายไปคุณจะได้รับข้อมูลที่จำเป็นต่อผู้ใช้อย่างไร มันมักจะหมายถึงการทำความเข้าใจกับ callgraph ในพื้นที่เพื่อให้คุณทราบว่าจะรับข้อมูลได้จากที่ไหน ตอนนี้สิ่งที่ง่ายกว่า: ค้นหาสิบซิงเกิลในแอปของคุณทำความเข้าใจการใช้งานแต่ละอัน (ซึ่งนำไปสู่ความต้องการที่จะเข้าใจรหัสฐาน 60%) และคัดลอกออก หรือรับรหัสที่คุณเข้าใจอยู่แล้ว (เพราะคุณกำลังทำอยู่ตอนนี้) และการฉีก singletons ที่ใช้อยู่ที่นั่น? หากการปรับโครงสร้างไม่ได้เป็นแบบเชิงกลต้องใช้ความรู้เพียงเล็กน้อยถึงไม่มีรหัสโดยรอบก็ไม่ได้ใช้ในการรวมมัน
  • การปรับโครงสร้างจะต้องเป็นไปโดยอัตโนมัติ นี่เป็นพื้นฐานของความคิดเห็น แต่นี่จะไป การปรับโครงสร้างเล็กน้อยนั้นสนุกและน่าพึงพอใจ การรีแฟคเตอร์จำนวนมากนั้นน่าเบื่อและน่าเบื่อ การทิ้งโค้ดที่คุณเพิ่งทำงานในสถานะที่ดีขึ้นจะทำให้คุณรู้สึกดีและอบอุ่นก่อนที่คุณจะไปยังสิ่งที่น่าสนใจมากขึ้น การพยายามปรับโครงสร้างฐานข้อมูลทั้งหมดจะทำให้คุณผิดหวังและโมโหโปรแกรมเมอร์ที่เขียนมัน หากคุณต้องการที่จะทำการปรับเปลี่ยนครั้งใหญ่มันจะต้องเป็นไปโดยอัตโนมัติส่วนใหญ่เพื่อลดความยุ่งยาก นี่คือจุดรวมของสองจุดแรก: คุณสามารถทำการ refactoring โดยอัตโนมัติหากคุณสามารถค้นหารหัสที่ไม่ดี (เช่นพบได้ง่าย) และทำการเปลี่ยนโดยอัตโนมัติ (เช่นกลไก)
  • การปรับปรุงอย่างค่อยเป็นค่อยไปทำให้ธุรกิจดีขึ้น การเปลี่ยนโครงสร้างครั้งใหญ่ทำให้เกิดความยุ่งยากอย่างไม่น่าเชื่อ หากคุณสร้างรหัสใหม่คุณจะได้รับความขัดแย้งที่เกิดขึ้นกับคนอื่น ๆ เพราะคุณเพิ่งแยกวิธีการที่พวกเขาเปลี่ยนเป็นห้าส่วน เมื่อคุณ refactor ชิ้นส่วนขนาดที่สมเหตุสมผลคุณจะได้รับความขัดแย้งกับคนไม่กี่คน (1-2 เมื่อแยก megafunction 600 บรรทัด, 2-4 เมื่อแยกวัตถุเทพเจ้าออกมา 5 เมื่อแยก singleton ออกจากโมดูล ) แต่คุณจะมีข้อขัดแย้งเหล่านั้นอยู่ดีเนื่องจากการแก้ไขหลักของคุณ เมื่อคุณทำการปรับเปลี่ยนโค้ดเบสให้กว้างคุณจะขัดแย้งกับทุกคน. ไม่พูดถึงว่ามันผูกนักพัฒนาไม่กี่วัน การปรับปรุงอย่างค่อยเป็นค่อยไปทำให้การแก้ไขรหัสแต่ละครั้งใช้เวลานานขึ้นเล็กน้อย สิ่งนี้ทำให้คาดการณ์ได้มากขึ้นและไม่มีช่วงเวลาที่มองเห็นได้เมื่อไม่มีสิ่งใดเกิดขึ้นยกเว้นการล้างข้อมูล

12

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

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

ฉันเป็นการสมัครรับหลักการ Boy Scoutเป็นการส่วนตัวแต่คนอื่น ๆ

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

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

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


2
ฉันเห็นด้วยในหลักการทั้งหมด แต่ในหลาย ๆ บริษัท มันลงมาทั้งเวลาและเงิน หากส่วน "เรียบร้อย" ใช้เวลาเพียงไม่กี่นาทีก็ไม่เป็นไร แต่เมื่อการประมาณค่าเรียบร้อยมากขึ้น (สำหรับคำจำกัดความของคำว่าใหญ่) คุณผู้ที่เข้ารหัสต้องมอบหมายการตัดสินใจให้เจ้านายของคุณหรือ ผู้จัดการโครงการ. ไม่ใช่ที่ของคุณที่จะตัดสินใจคุณค่าของเวลาที่ใช้ไป การทำงานกับ bug fix X หรือคุณสมบัติใหม่ Y อาจมีมูลค่าสูงกว่ามากสำหรับโครงการ / บริษัท / ลูกค้า
ozz

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

ใช่ตามที่คุณสัมผัสมีเหตุผลมากมายที่การผ่าตัดรหัสสำคัญอาจหรือไม่เป็นความคิดที่ดี: ลำดับความสำคัญการพัฒนาอื่น ๆ อายุการใช้งานของซอฟต์แวร์ทรัพยากรการทดสอบประสบการณ์นักพัฒนาการมีเพศสัมพันธ์รอบการเปิดตัวความคุ้นเคยกับรหัส ฐาน, เอกสาร, ภารกิจสำคัญ, วัฒนธรรมของ บริษัท ฯลฯ ฯลฯ มันเป็นคำพิพากษา
Robbie Dee

4

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

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

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


3

Re: "รหัสต้นฉบับอาจทำงานไม่ถูกต้อง":

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


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

3

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

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

ถ้าฉันจำได้ถูกต้องว่าหนังสือ Refactoring บอกว่าต้องทำการทดสอบอยู่ตลอดเวลาดังนั้นมันจึงเป็นส่วนหนึ่งของกระบวนการ


3

ทำครอบคลุมการทดสอบอัตโนมัติ

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

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

อาจเป็นการเหมาะสมที่จะ จำกัด จำนวนเวลาที่คุณลงทุน


1

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

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

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

IntegrationTestCase1()
{
    var input = ReadDataFile("path\to\test\data\case1in.ext");
    bool validInput = ValidateData(input);
    Assert.IsTrue(validInput);

    var processedData = ProcessData(input);
    Assert.AreEqual(0, processedData.Errors.Count);

    bool writeError = WriteFile(processedData, "temp\file.ext");
    Assert.IsFalse(writeError);

    bool filesAreEqual = CompareFiles("temp\file.ext", "path\to\test\data\case1out.ext");
    Assert.IsTrue(filesAreEqual);
}

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

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

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