ฉันจะเขียนการทดสอบหน่วยสำหรับหุ่นยนต์ (และอุปกรณ์เชิงกลอื่น ๆ ) ได้อย่างไร


22

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

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

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

หรือฉันแค่เข้าใจผิดว่าการทดสอบหน่วยควรทำงานอย่างไร

( ถ้ามันสำคัญนี่คือรหัสมันเขียนด้วยภาษา C ++ และฉันมีส่วนร่วมในFRC )

คำตอบ:


21

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

น่าเสียดายที่มีปัญหาบางอย่างที่คุณต้องเอาชนะ:

  • การเย้ยหยันสิ่งที่เป็นภาษาระดับต่ำนั้นเป็นเรื่องยากมากขึ้น (และการทำงานมากขึ้น)
  • การเยาะเย้ยสิ่งที่ระดับฮาร์ดแวร์เป็นเรื่องยากมากขึ้น (และการทำงานมากขึ้น)

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


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

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

4
@DavidWallace เป็นความคิดเล็ก ๆ น้อย ๆ อาหารเมื่อใช้ TDD / BDD ประโยชน์ของการทดสอบหน่วยที่เกิดขึ้นทันที ในสถานที่แรกโดยอนุญาตให้รหัสที่จะ refactored มั่นใจทันทีและประการที่สองโดยการสนับสนุนการดำเนินการจะถูก จำกัด การใช้งานขั้นต่ำที่จำเป็นในการตอบสนองการทดสอบ
S.Robins

4
@ แมตต์ความคิดที่ไม่ดีและฉันรู้จากประสบการณ์ จะเกิดอะไรขึ้นถ้าโค้ดที่อยู่ภายใต้การทดสอบล้มเหลวอย่างหนักมากและแขนหุ่นยนต์ชนกับกำแพงทำลายชิ้นส่วนของฮาร์ดแวร์ xxxx $
stijn

2
@ เคลือบเงา: หุ่นยนต์ของเรามีความยาวประมาณ 2 ฟุต 3 ฟุตคูณ 4 ฟุตและหนักประมาณ 150 ปอนด์ ชุดอุปกรณ์ / การลงทะเบียนมีค่าใช้จ่าย 5,000 ดอลลาร์ต่อปีและเรามักจะระดมทุนอีก 5 ถึง 10k เพื่อซื้อชิ้นส่วนเพิ่มเติม สถานการณ์กรณีที่เลวร้ายที่สุดอาจมีราคาสูงกว่า $ 10;)
Michael0x2a

10

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

ตัวอย่างเช่นหากคุณต้องการออกแบบโปรโตคอลการส่งสัญญาณที่ใช้ I2C คุณสามารถทดสอบรหัสของคุณได้ว่ากำลังสร้างสัญญาณ I2C ที่ถูกต้องโดยไม่ต้องเชื่อมต่อฮาร์ดแวร์เข้ากับการทดสอบของคุณ

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

สิ่งนี้เหมาะสมกับสิ่งที่ Oleksi กล่าวไว้ในคำตอบของเขาโดยปกติแล้วมันจะทำงานได้มากขึ้นในการจำลองสิ่งต่าง ๆ ในระดับฮาร์ดแวร์ แต่มันก็ไม่ยากนักหากคุณยังคงเลเยอร์โค๊ด - โค๊ด / โทรน้อยที่สุดเท่าที่จะทำได้ ฮาร์ดแวร์.

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

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


2

ฉันสามารถบอกคุณได้ว่าพวกเขาทำได้บน Flight Simulators อย่างไร

ก่อนอื่นคุณจะได้รับคำตอบเพียงครึ่งเดียวหากคุณถามคำถามนี้กับโปรแกรมเมอร์เท่านั้นดังนั้นคุณควรจะโพสต์ข้อความนี้ทางhttp://electronics.stackexchange.comขณะที่คุณอยู่ที่นั่น

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

เลเยอร์ฮาร์ดแวร์นั้นเป็นใบ้

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

การปรับเทียบเป็นตารางอย่างง่ายที่มีการแบ่งส่วนระหว่างค่า min / max ในการวัดอินพุตเหล่านี้มักใช้เซอร์โว (เช่นโพเทนทิโอมิเตอร์เชิงเส้น, ทรานสดิวเซอร์, เครื่องเร่งความเร็ว ฯลฯ ) หรือในกรณีของเครื่องมือวัดคุณเพียงแค่ตัดสินความถูกต้องทางสายตาและปรับจนกระทั่งปรับเทียบ

เลเยอร์ซอฟต์แวร์นั้นตรงกันข้าม

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

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

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

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

การทดสอบตัวเองไม่จำเป็นต้องมีความซับซ้อนตราบใดที่ผลลัพธ์สามารถคาดการณ์ได้วัดได้และทำซ้ำได้


1

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

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