จะออกแบบซอฟต์แวร์ของเกมอย่างไรให้ง่ายต่อการทดสอบหน่วย?


25

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

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


6
ทำไมต้องเสียการทดสอบหน่วยการเขียนชั่วโมงทำงานเมื่อคุณมีกองทัพทาสที่ไม่มีที่สิ้นสุดอย่างแท้จริงเพื่อทำการทดสอบสำหรับคุณ? I kid, I kid ... ;)
Mike Strobel

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

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

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

คำตอบ:


25

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

สำหรับฉันมีสองสิ่งที่ฉันไม่ได้ทดสอบในฐานะส่วนหนึ่งของการทดสอบหน่วย:

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

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


6
ย่อหน้าแรกเป็นกุญแจสำคัญ ความจริงก็คือว่า TDD ต้องการให้คุณออกแบบรหัสของคุณได้ดีกว่าที่คุณคาดไม่ถึง แน่นอนว่าหลายคนคิดว่าพวกเขาเป็นผู้เชี่ยวชาญในการออกแบบ แต่แน่นอนว่าคนที่ประทับใจที่สุดกับทักษะของตัวเองมักจะเป็นคนที่เรียนรู้ได้มากที่สุด ...
dash-tom-bang

2
ฉันไม่เห็นด้วยที่จะต้องออกแบบให้ดีขึ้น ฉันได้เห็นสิ่งที่น่ารังเกียจมากมายที่อินเทอร์เฟซที่สะอาดก่อนหน้านี้ต้องถูกทุบเปิดและ encapsulation เสียเพื่อฉีดทดสอบที่ต้องพึ่งพา
Kylotan

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

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

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

19

Noel Llopis ได้ครอบคลุมการทดสอบหน่วยในระดับที่ฉันเชื่อว่าคุณกำลังมองหา:

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

ในขณะที่ประโยชน์ของเทคนิคนี้ชัดเจน แต่มีบางสิ่งที่คุณต้องระวัง:

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

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

9

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

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

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

ที่กล่าวว่าอย่าไปลงน้ำพยายามทดสอบทุก ๆ อย่างอิสระ เช่นเดียวกับการทดสอบและการออกแบบส่วนใหญ่ที่เกี่ยวกับการสร้างสมดุล


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

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

3

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

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

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


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

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