วิธีลบฟังก์ชั่นหรือคุณสมบัติเมื่อใช้ TDD


20

ในข้อความเกี่ยวกับ TDD ฉันมักจะอ่านเกี่ยวกับ "ลบการทำซ้ำ" หรือ "ปรับปรุงการอ่าน" ในระหว่างขั้นตอนการสร้างใหม่ แต่อะไรทำให้ฉันลบฟังก์ชันที่ไม่ได้ใช้ออก

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

มันเป็นการประหยัดเพียงแค่ลบb()และการทดสอบทั้งหมดที่ใช้หรือไม่ เป็นส่วนหนึ่งของ "ปรับปรุงการอ่าน" หรือไม่?


3
เพียงแค่เพิ่มการทดสอบอีกครั้งเพื่อตรวจสอบว่าฟังก์ชั่นไม่ได้อยู่แล้วไปแก้ไข testcases ล้มเหลว;)
ฆา Haglund

@FilipHaglund ขึ้นอยู่กับภาษานี้อาจเป็นไปได้ แต่เป็นรหัสเอกสารนี้จะดูแปลก
TobiMcNamobi

1
สำหรับใครก็ตามที่อาจไม่รู้จักดีกว่า: @ ความคิดเห็นของ FilipHaglund เป็นเรื่องตลกอย่างแน่นอน อย่าทำอย่างนั้น
jhyot

คำตอบ:


16

ใช่แน่นอน รหัสที่ง่ายที่สุดในการอ่านคือสิ่งที่ไม่มีอยู่

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


@ jpmc26 Agile, Man, Agile! :-)
TobiMcNamobi

1
"รหัสที่ง่ายที่สุดในการอ่านคือสิ่งที่ไม่มีอยู่" - ฉันกำลังแขวนใบเสนอราคาบนกำแพง: D
winkbrace

27

การลบวิธีสาธารณะไม่ใช่ "การเปลี่ยนสถานะใหม่" - การเปลี่ยนสถานะกำลังเปลี่ยนการใช้งานในขณะที่ยังคงผ่านการทดสอบที่มีอยู่

อย่างไรก็ตามการลบวิธีที่ไม่จำเป็นออกเป็นการเปลี่ยนแปลงการออกแบบที่สมเหตุสมผลอย่างสมบูรณ์แบบ

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

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

มีสองวิธีในการลบวิธี ทั้งทำงานในสถานการณ์ที่แตกต่าง:

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

  2. ลบการทดสอบที่คุณรู้สึกว่าล้าสมัย เรียกใช้ชุดทดสอบทั้งหมดของคุณด้วยรหัสครอบคลุม ลบวิธีการที่ชุดทดสอบไม่ได้ใช้

(สิ่งนี้อนุมานว่าชุดทดสอบของคุณมีความครอบคลุมที่ดีในการเริ่มต้นด้วย)


10

ในความเป็นจริง f () แทนที่การเรียกทั้งหมดไปยัง b () ด้วยข้อยกเว้นของการทดสอบหน่วยที่กำหนด / อธิบาย b ()

IMHO วัฏจักร TDD โดยทั่วไปจะมีลักษณะเช่นนี้:

  • เขียนการทดสอบที่ล้มเหลวสำหรับ f () (อาจขึ้นอยู่กับการทดสอบสำหรับ b ()): การทดสอบเป็นสีแดง

  • ใช้ f () -> การทดสอบกลายเป็นสีเขียว

  • refactor : -> ลบ b () และการทดสอบทั้งหมดสำหรับ b ()

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


4

ใช่แล้ว.

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


9
คุณพลาดส่วน "วิธีการ"
JeffO

2

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

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

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

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

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

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

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


2

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

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


การลบรหัสไม่ใช่ปัญหาโดยทั่วไป ฉันชอบที่จะลบเพื่อลบบรรทัดฟังก์ชั่นหรือ ... ดีโมดูลทั้งหมด! ถ้าเป็นไปได้. และฉันทำสิ่งนี้ทั้งหมดโดยมีหรือไม่มี TDD แต่: มีจุดหนึ่งในเวิร์กโฟลว์ TDD ที่มีการลบรหัส (ไม่ใช่ดูลิป) หรือไม่? ถ้าไม่มันจะถูกลบต่อไป แต่จะมี นั่นคือคำถามของฉัน
TobiMcNamobi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.