TDD กับผลผลิต


131

ในโครงการปัจจุบันของฉัน (เกมใน C ++) ฉันตัดสินใจว่าฉันจะใช้ Test Driven Development 100% ในระหว่างการพัฒนา

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

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

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

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

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

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


@Nairou: คุณสามารถลอง "ทำให้โครงการเสร็จสมบูรณ์" ได้ตลอดเวลา! ทำสาขาตอนนี้ เพียงแค่เขียนรหัสลงไป แต่ จำกัด สิ่งที่คุณทำไม่ว่าจะเป็นเวลาหรือจำนวนเอนทิตีของเกมและดูว่าคุณไปเร็วขึ้นหรือไม่ จากนั้นคุณสามารถละเว้นสาขานั้นกลับไปที่หีบและ TDD จากที่นั่นและดูความแตกต่าง
quamrana

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

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

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

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

คำตอบ:


77

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

  • เวลา / ผลผลิต: การทดสอบการเขียนช้ากว่าการไม่เขียนการทดสอบ หากคุณกำหนดขอบเขตดังกล่าวฉันก็เห็นด้วย อย่างไรก็ตามหากคุณใช้ความพยายามแบบขนานที่คุณใช้วิธีการที่ไม่ใช่ TDD โอกาสที่เวลาที่คุณใช้รหัสที่มีอยู่ break-detect-debug-and-fix จะทำให้คุณติดลบ สำหรับฉัน TDD เป็นวิธีที่เร็วที่สุดที่ฉันสามารถไปได้โดยไม่ลดทอนความมั่นใจในโค้ดของฉัน หากคุณพบสิ่งต่าง ๆ ในวิธีการของคุณที่ไม่ได้เพิ่มมูลค่าให้กำจัด
  • จำนวนการทดสอบ: ถ้าคุณเขียนโปรแกรม N สิ่งคุณต้องทดสอบสิ่ง N เพื่อถอดความหนึ่งในบรรทัดของ Kent Beck " ทดสอบเฉพาะในกรณีที่คุณต้องการให้มันทำงาน "
  • ติดขัดหลายชั่วโมง: ฉันก็ทำเหมือนกัน (บางครั้งและไม่ใช่> 20 นาทีก่อนที่ฉันจะหยุดสาย) .. มันเป็นเพียงรหัสของคุณที่บอกคุณว่าการออกแบบนั้นต้องใช้งานบ้าง การทดสอบเป็นเพียงไคลเอนต์อื่นสำหรับคลาส SUT ของคุณ หากการทดสอบพบว่ามันยากที่จะใช้ประเภทของคุณโอกาสในการผลิตของลูกค้าจะเป็นเช่นนั้น
  • การทดสอบที่คล้ายกัน tedium: สิ่งนี้ต้องการบริบทเพิ่มเติมสำหรับฉันในการเขียนโต้แย้ง ที่กล่าวว่าหยุดและคิดเกี่ยวกับความคล้ายคลึงกัน คุณสามารถ data-drive ทดสอบเหล่านั้นได้หรือไม่? เป็นไปได้หรือไม่ที่จะเขียนการทดสอบเทียบกับประเภทฐาน? จากนั้นคุณเพียงแค่เรียกใช้ชุดการทดสอบเดียวกันกับแต่ละแหล่งที่มา ฟังการทดสอบของคุณ เป็นคนขี้เกียจที่เหมาะสมและดูว่าคุณสามารถหาวิธีหลีกเลี่ยงความเบื่อหน่ายได้ไหม
  • การหยุดคิดเกี่ยวกับสิ่งที่คุณต้องทำต่อไป (การทดสอบ / ข้อมูลจำเพาะ) ไม่ใช่เรื่องเลวร้าย ในทางตรงกันข้ามขอแนะนำให้คุณสร้าง "สิ่งที่ถูกต้อง" โดยปกติถ้าฉันไม่สามารถคิดวิธีทดสอบได้ฉันมักไม่สามารถคิดถึงการใช้งานได้เช่นกัน เป็นความคิดที่ดีที่จะลบล้างแนวคิดการใช้งานจนกว่าคุณจะไปถึงที่นั่น .. อาจเป็นทางออกที่ง่ายกว่าซึ่งถูกบดบังด้วยการออกแบบล่วงหน้าแบบ YAGNI-ish

และนั่นนำฉันไปสู่คำถามสุดท้าย: ฉันจะดีขึ้นได้อย่างไร คำตอบ (หรือ An) ของฉันคืออ่านสะท้อนและฝึกฝน

เช่นช้าไปเรื่อย ๆ

  • ไม่ว่าจังหวะของฉันจะสะท้อนถึง RG [Ref] RG [Ref] RG [Ref] หรือมันคือ RRRRGRRef
  • % เวลาที่ใช้ในสถานะ Red / Compile Error
  • ฉันติดอยู่ในสถานะบิวด์แดง / แตกหรือไม่?

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

@Nairoi - ไม่แน่ใจว่าคุณใช้นักวิ่งทดสอบประเภทใด ฉันเพิ่งเรียนรู้ชื่อสิ่งที่ฉันต้องการจะสื่อ รูปแบบการติดตั้งบทคัดย่อ [ goo.gl/dWp3k] สิ่งนี้ยังต้องการให้คุณเขียนโปรแกรมฟิกซ์เจอร์จำนวนมากเนื่องจากมี SUT ที่เป็นรูปธรรม หากคุณต้องการรัดกุมยิ่งขึ้นให้ดูเอกสารของนักวิ่งของคุณ เช่น NUnit รองรับการติดตั้งการทดสอบแบบพารามิเตอร์และทั่วไป (ตอนนี้ฉันค้นหาแล้ว) goo.gl/c1eEQดูเหมือนสิ่งที่คุณต้องการ
Gishu

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

@asgeo - ไม่สามารถแก้ไขความคิดเห็นได้ .. ลิงก์ได้รับวงเล็บต่อท้ายซึ่งควรจะทำงาน - goo.gl/dWp3k
Gishu

+1 สำหรับ 'ติดขัดเป็นอาการของการออกแบบที่ต้องใช้งานมากขึ้น' แม้ว่า .. จะเกิดอะไรขึ้นเมื่อคุณติด (เหมือนฉัน) ที่การออกแบบ?
lurscher

32

คุณไม่ต้องการความคุ้มครองการทดสอบ 100% เน้นการปฏิบัติ


2
หากคุณไม่มีการทดสอบครอบคลุม 100% คุณไม่มีความมั่นใจ 100%
Christopher Mahan

60
คุณไม่มีความมั่นใจ 100% แม้จะครอบคลุมการทดสอบ 100% นั่นเป็นการทดสอบ 101 การทดสอบไม่สามารถแสดงให้เห็นว่ารหัสไม่มีข้อบกพร่อง ในทางตรงกันข้ามพวกเขาสามารถแสดงให้เห็นว่ามันมีข้อบกพร่อง
CesarGon

7
สำหรับสิ่งที่คุ้มค่าซึ่งเป็นหนึ่งในผู้สนับสนุน TDD หลงใหลมากที่สุดบ๊อบมาร์ตินไม่แนะนำให้ความคุ้มครอง 100% - blog.objectmentor.com/articles/2009/01/31/... ในอุตสาหกรรมการผลิต (ที่ได้รับแตกต่างจากซอฟต์แวร์ในหลาย ๆ ด้าน) ไม่มีใครมั่นใจ 100% เพราะพวกเขาสามารถใช้ความพยายามเพียงเล็กน้อยเพื่อให้มั่นใจ 99%
โอกาส

นอกจากนี้ (อย่างน้อยครั้งสุดท้ายที่ฉันตรวจสอบเครื่องมือที่เรามี) รายงานความครอบคลุมโค้ดเกี่ยวข้องกับว่ามีการดำเนินการบรรทัด แต่ไม่รวมถึงการครอบคลุมค่า - เช่นวันนี้ฉันมีข้อผิดพลาดรายงานที่ฉันมีเส้นทางทั้งหมดผ่านรหัสดำเนินการในการทดสอบ เนื่องจากมีบรรทัดเหมือนa = x + yและแม้ว่าทุกบรรทัดในรหัสจะถูกดำเนินการในการทดสอบการทดสอบทดสอบเฉพาะสำหรับกรณีที่ y = 0 ดังนั้นข้อผิดพลาด (ควรได้รับa = x - y) ไม่เคยพบในการทดสอบ
Pete Kirkham

@ โอกาส - ฉันได้อ่านหนังสือของ Robert Martin "Clean coder ... " บางชื่อยาว มันบอกว่าในหนังสือเล่มนั้นว่ามันควรจะเป็น 100% asymptotically ปกคลุมไปด้วยการทดสอบซึ่งใกล้เคียงกับ 100% และลิงก์บล็อกไม่ทำงานอีกต่อไป
Darius.V

22

TDD ยังคงทำให้ฉันช้าลงอย่างมาก

มันผิดจริง

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

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

เวลาที่ผ่านไปน่าจะเป็นเท่าเดิม ซอฟต์แวร์ TDD จะมีคุณภาพดีขึ้นอย่างมาก


6
แล้วทำไมฉันต้องใช้ TDD "เวลาที่ผ่านไปเหมือนกัน"

21
@Peter Long: คุณภาพของรหัส ปี "การทดสอบ" คือวิธีที่เราปิดท้ายด้วยซอฟต์แวร์อึที่ทำงานได้เป็นส่วนใหญ่
S.Lott

1
@ ปีเตอร์คุณต้องล้อเล่น คุณภาพของโซลูชัน TDD นั้นเหนือกว่ามาก
มาร์คโธมัส

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

7
@Peter Long: "เวลาที่ผ่านไปเหมือนกัน" ... และ ณ จุดใด ๆ ในช่วงเวลานั้นคุณสามารถส่งรหัสทำงานได้
Frank Shearar

20

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

นี่ทำให้ฉันสงสัยว่าคุณกำลังทำตามขั้นตอน "Refactor" ของ TDD มากแค่ไหน

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

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

ประเด็นทางปรัชญาสองประการเกี่ยวกับ TDD ที่อาจเป็นประโยชน์:

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

แก้ไข:ในหัวข้อของปรัชญาของการทดสอบหน่วยฉันคิดว่านี่อาจจะน่าสนใจสำหรับคุณที่จะอ่าน: วิถีแห่ง Testivus

และการปฏิบัติมากขึ้นถ้าไม่จำเป็นต้องเป็นประโยชน์มากจุด:

  • คุณพูดถึง C ++ เป็นภาษาการพัฒนาของคุณ ฉันฝึกฝน TDD อย่างแพร่หลายใน Java โดยใช้ห้องสมุดที่ยอดเยี่ยมอย่าง JUnit และ Mockito อย่างไรก็ตามฉันพบว่า TDD ใน C ++ น่าผิดหวังมากเนื่องจากไม่มีไลบรารี (โดยเฉพาะอย่างยิ่งเฟรมเวิร์กที่เยาะเย้ย) ที่มีอยู่ ในขณะที่ประเด็นนี้ไม่ได้ช่วยคุณในสถานการณ์ปัจจุบันของคุณมากนักฉันหวังว่าคุณจะนำมาพิจารณาก่อนที่จะทำการ TDD โดยสิ้นเชิง

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

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

1
C ++ นั้นยากต่อการทดสอบหน่วย (ภาษาไม่สามารถทำสิ่งต่าง ๆ ที่ทำให้ mocks ง่าย) ฉันสังเกตเห็นว่าฟังก์ชั่นซึ่งเป็น "ฟังก์ชั่น" (ใช้งานได้เฉพาะกับข้อโต้แย้งผลลัพธ์ที่ออกมาเป็นค่าตอบแทน / params) จะทดสอบได้ง่ายกว่า "โพรซีเดอร์" (return void, no args) ฉันพบว่าจริง ๆ แล้วมันจะง่ายกว่าในการทดสอบหน่วยรหัส C modular แบบฝีมือดีกว่ารหัส C ++ คุณไม่ต้องเขียนใน C แต่คุณสามารถทำตามตัวอย่างของโมดูลาร์ ฟังดูเพี้ยนไปหมด แต่ฉันได้ทำการทดสอบหน่วยใน "bad C" ซึ่งทุกอย่างเป็นสากลและมันง่ายมาก - ทุกสถานะพร้อมใช้งานเสมอ!
อานนท์

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

1
กรอบการเยาะเย้ยของ Google C ++ (รวมเข้ากับการทดสอบ google C ++ fw) - ห้องสมุดจำลองที่มีประสิทธิภาพและยืดหยุ่นสูง - มีความยืดหยุ่นคุณลักษณะที่หลากหลาย - ค่อนข้างเทียบเคียงกับกรอบการเยาะเย้ยอื่น ๆ
ratkok

9

คำถามที่น่าสนใจมาก

สิ่งสำคัญที่ควรทราบคือ C ++ นั้นไม่สามารถทดสอบได้ง่ายมากและโดยทั่วไปเกมก็เป็นตัวเลือกที่แย่มากสำหรับ TDD คุณไม่สามารถทดสอบว่า OpenGL / DirectX วาดสามเหลี่ยมสีแดงด้วยไดรเวอร์ X และสีเหลืองพร้อมไดรเวอร์ Y ได้อย่างง่ายดาย หากเวกเตอร์ปกติของ bump map ไม่ถูกพลิกหลังจาก shader แปลง หรือคุณสามารถทดสอบปัญหาการตัดผ่านไดรเวอร์รุ่นที่มีความแตกต่างกันและอื่น ๆ พฤติกรรมการวาดที่ไม่ได้กำหนดเนื่องจากการโทรที่ไม่ถูกต้องสามารถทดสอบได้เฉพาะกับการตรวจสอบรหัสที่ถูกต้องและ SDK ในมือ เสียงก็เป็นตัวเลือกที่ไม่ดีเช่นกัน การทำมัลติเธรดซึ่งค่อนข้างสำคัญสำหรับเกมค่อนข้างไร้ประโยชน์ต่อการทดสอบหน่วย ดังนั้นมันจึงเป็นเรื่องยาก

โดยทั่วไปเกมจะมี GUI เสียงและเธรดมากมาย GUI แม้จะมีส่วนประกอบมาตรฐานที่คุณสามารถส่ง WM_ ไปได้นั้นยากต่อการทดสอบหน่วย

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

จากนั้นอีกครั้งฉันไม่ใช่กูรูหรือผู้สอนศาสนาของ TDD ดังนั้นเอาทุกสิ่งนั้นไปด้วยเม็ดเกลือ

ฉันอาจจะเขียนการทดสอบบางอย่างสำหรับองค์ประกอบหลักที่สำคัญ (เช่นเมทริกซ์ไลบรารี, คลังภาพ) เพิ่มกลุ่มของabort()อินพุตที่ไม่คาดคิดในทุกฟังก์ชั่น และที่สำคัญที่สุดคือจดจ่อกับรหัสที่ทนต่อการยืดหยุ่น / ที่ไม่แตกง่าย

เกี่ยวกับข้อผิดพลาดเดียวการใช้ C ++ ฉลาด ๆ และการออกแบบที่ดีนั้นเป็นวิธีที่ดีในการป้องกันพวกเขา

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


3
+1 ฉันชอบแนวคิดของ TDD มากและใช้งานได้ทุกที่ที่ทำได้ แต่คุณยกประเด็นที่สำคัญมากที่ผู้สนับสนุน TDD เงียบไปด้วยความอยากรู้อยากเห็น มีหลายประเภทของการเขียนโปรแกรมตามที่คุณได้ชี้ให้เห็นว่าการเขียนการทดสอบหน่วยที่มีความหมายนั้นยากมากหากไม่สามารถทำได้ ใช้ TDD ในจุดที่เหมาะสม แต่โค้ดบางประเภทพัฒนาและทดสอบได้ดีกว่าในรูปแบบอื่น
Mark Heath

@ Mark: yup ดูเหมือนว่าไม่มีใครสนใจเกี่ยวกับการรวมการทดสอบในปัจจุบันคิดว่าเพราะพวกเขาได้รับชุดทดสอบอัตโนมัติทุกอย่างจะทำงานได้อย่างน่าอัศจรรย์เมื่อรวบรวมและลองกับข้อมูลจริง
gbjbaanb

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

6

ฉันเห็นด้วยกับคำตอบอื่น ๆ แต่ฉันต้องการเพิ่มจุดที่สำคัญมาก: การปรับค่าใช้จ่ายอีกครั้ง !!

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


4

คนอื่นจะอยู่รอดได้อย่างไรโดยไม่ทำลายประสิทธิภาพและแรงจูงใจทั้งหมด?

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

TDD เกี่ยวกับการมีความถ่อมใจที่จะรู้ว่าคุณ (และฉัน!) ทำผิดพลาด

สำหรับฉันเวลาที่เขียน unittests มากกว่าบันทึกในเวลาการดีบักที่ลดลงสำหรับโครงการที่ทำโดยใช้ TDD ตั้งแต่ต้น

หากคุณไม่ทำผิดพลาดบางที TDD อาจไม่สำคัญสำหรับคุณเท่านี้สำหรับฉัน!


ดีที่คุณมีข้อบกพร่องในรหัส TDD ของคุณเช่นกัน;)
Coder

จริง! แต่พวกมันมักจะเป็นบั๊กประเภทต่าง ๆ หากทำ TDD อย่างถูกต้อง ฉันเดาว่ารหัสจะต้องมีข้อบกพร่อง 100% ที่จะเสร็จสมบูรณ์ไม่ถูกต้อง แต่ถ้าหนึ่งกำหนดข้อผิดพลาดเช่นการเบี่ยงเบนจากพฤติกรรมการทดสอบหน่วยที่กำหนดไว้แล้วผมคิดว่ามันเป็นข้อผิดพลาดฟรี :)
ทอม

3

ฉันพูดเพียงไม่กี่:

  1. ดูเหมือนว่าคุณกำลังพยายามที่จะทดสอบทุกอย่าง คุณอาจไม่ควรเพียงแค่กรณีที่มีความเสี่ยงสูงและ edge ของชิ้นส่วนของรหัส / วิธีการเฉพาะ ฉันค่อนข้างมั่นใจว่ากฎ 80/20 จะมีผลกับที่นี่: คุณใช้การทดสอบการเขียน 80% สำหรับรหัสหรือกรณีของคุณที่ไม่ครอบคลุม 20% สุดท้าย

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

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


1

ใช่การเขียนการทดสอบและรหัสอาจใช้เวลานานกว่าการเขียนโค้ด แต่การเขียนโค้ดและการทดสอบหน่วยที่เกี่ยวข้อง (โดยใช้ TDD) นั้นสามารถคาดเดาได้มากกว่าการเขียนโค้ดแล้วจึงทำการดีบั๊ก

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

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


0

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

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