แนวปฏิบัติที่เหมาะสมที่สุดเมื่อทำการทดสอบหน่วยสำหรับการพัฒนาแบบฝัง


45

ฉันกำลังมองหากลยุทธ์การปฏิบัติที่ดีที่สุดสำหรับโค้ดทดสอบหน่วยที่เขียนขึ้นสำหรับระบบฝังตัว โดยระบบฝังตัวฉันหมายถึงรหัสเช่นไดรเวอร์อุปกรณ์ตัวจัดการ ISR เป็นต้นสิ่งที่ใกล้เคียงกับโลหะ

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

ปรับปรุง

ฉันเจอโครงร่างการทดสอบ C ซึ่งดูเหมือนว่าจะประสบความสำเร็จในการทดสอบโครงการแบบฝัง มันใช้ความคิดของฮาร์ดแวร์เยาะเย้ย ตรวจสอบความสามัคคี , CMockและอาจCeedling

อัพเดท 06 ก.ค. 2559

มาทั่วcmocka - ดูเหมือนว่าจะทำงานอย่างแข็งขันมากขึ้น


1
ในสถานการณ์ที่คล้ายคลึงกันเราไป Cmocka
Mawg

ฉันได้เขียนบทแนะนำอย่างละเอียดเกี่ยวกับหัวข้อ: การทดสอบหน่วยฝังตัวแอปพลิเคชัน C ด้วย Ceedling
Dmitry Frank

คำตอบ:


28

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

การทดสอบชิ้นส่วนเปล่าที่แท้จริงอย่างแท้จริงของระบบสมองกลฝังตัวนั้นมักจะเป็นแอพพลิเคชั่นที่แยกออกจากกัน (Unit test?) ที่ค้อนเฟิร์มแวร์นั้นดีกว่าสิ่งที่แอพพลิเคชั่นสามารถทำได้ ระบบอัตโนมัติสามารถทำได้ - มีค่าใช้จ่าย แต่ไม่ใช่เรื่องปกติ

ยกเว้นว่าคุณมีงบประมาณในการสร้างชุดทดสอบฮาร์ดแวร์รวมถึง ICE แบบเต็ม นี่เป็นเรื่องปกติเพราะการทดสอบการใช้งานมีขนาดเล็ก


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

3
ทุกผลิตภัณฑ์ของเรามี Hardware Abstraction Layer พร้อมกับการติดตั้งไดรเวอร์สำหรับแพลตฟอร์มเป้าหมายและพีซี สิ่งนี้ทำให้เราสามารถทำการทดสอบหน่วยได้อย่างง่ายดาย ข้อดีอื่น ๆ : เราสามารถทำการทดสอบระบบได้อย่างรวดเร็วและพัฒนาซอฟต์แวร์ส่วนใหญ่โดยไม่ต้องใช้ฮาร์ดแวร์ใด ๆ
MaR

15

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

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

การใช้ TeraTerm เป็นหัวฉีดสัญญาณพอร์ตอนุกรมและเขียนมาโคร TeraTerm บางส่วน (ใช้เวลาประมาณ 20 นาที) มีชุดการทดสอบอัตโนมัติขนาดใหญ่ซึ่งสามารถทำงานกับส่วนใด ๆ ของระบบฝังตัว - ไม่ว่าเลเยอร์ไดรเวอร์, O / S เลเยอร์ 4-5 เป็นต้น TeraTerm: http://en.sourceforge.jp/projects/ttssh2/

หากพอร์ตอนุกรมไม่พร้อมใช้งานในระบบฝังตัวให้ใช้เครื่องมือฮาร์ดแวร์เพื่อแปลงข้อมูลพอร์ต USB / อนุกรมเป็นสัญญาณดิจิตอล (เช่นราคาไม่แพงและง่ายต่อการบรรลุ) เมื่อคุณอ่านสิ่งนี้ฉันใช้ไมโครคอนโทรลเลอร์ $ 30 (UBW: http://www.schmalzhaus.com/UBW32/ ) เพื่อทดสอบระบบฝังตัวสำหรับการผลิตโดยการฉีดกระตุ้นผ่านมาโคร TeraTerm ซึ่งส่งผ่าน USB / ซีเรียลไปยัง ไมโครคอนโทรลเลอร์ซึ่งกำลังเรียกใช้เฟิร์มแวร์ที่ปรับเปลี่ยนซึ่งออกกำลังกายอินพุตดิจิตอลและตรวจสอบเอาต์พุตดิจิตอลของระบบฝังตัวเป้าหมาย ร่วมกับสิ่งนี้เราพัฒนาสคริปต์ python (ใช้ pyserial และ pexpect) เพื่อทำให้การฉีดข้อมูลและการตรวจสอบข้อมูลเป็นไปโดยอัตโนมัติ ไม่ยากและไม่มีราคาแพง. จากประสบการณ์ของฉันผู้จัดการใช้เม็ดเงินขนาดใหญ่ (เช่นอุปกรณ์ทดสอบ $ 30,000) เมื่อทีมทดสอบไม่มีประสบการณ์และไม่สามารถเข้าใจถึงวิธีแก้ปัญหาที่ง่ายเหล่านี้ - โชคไม่ดีที่อุปกรณ์เหล็กขนาดใหญ่ทั่วไปมักไม่รวมกรณีทดสอบ ซึ่งจับจังหวะเวลา / กรณีที่แย่ที่สุดของระบบเป้าหมาย ดังนั้นวิธีการที่ไม่แพงจึงเป็นสิ่งที่ดีกว่าสำหรับการครอบคลุมการทดสอบ เชื่อหรือไม่.


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

2
อย่าเพิ่งเริ่มต้นกับ LabView สินั่นเป็นเรื่องที่น่ากลัว
Jonathan Cline IEEE

1
วิศวกรทดสอบของเราชอบ LabView ฉันไม่เข้าใจตัวเองมากนัก
tehnyit

นี่ค่อนข้างใกล้เคียงกับสิ่งที่ฉันทำสำหรับการทดสอบต่าง ๆ มีเพียงฉันเท่านั้นที่ใช้ Python และไลบรารี่อนุกรมของพวกเขา จากนั้นฉันสามารถเสียบการทดสอบระดับต่ำของฉันลงในเครื่องทดสอบของ Python พร้อมกับบางอย่างเช่น Flask / Qt เพื่อให้ส่วนหน้าใช้งานง่ายเช่นกัน
radix07

5

นี่เป็นปัญหาที่ยากมาก

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

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


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

@tehnyit - ใช่นั่นคือเหตุผลที่เราตัดสินใจพัฒนาระบบอัตโนมัติ บางครั้งสิ่งที่ไม่สามารถทำได้ด้วยตนเองเลย แต่การทดสอบหน่วยจะต้องครอบคลุมและครอบคลุมปัญหาเวลา ดังนั้นคุณไม่มีทางเลือกมากนัก แต่ระบบอัตโนมัติในระดับนี้เป็นสิ่งที่ต้องทำ
littleadv

4

แก้ไข: คำตอบของฉันใกล้กับของ mattnz ฉันคิดว่า ...


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

ทดสอบการทำงานภายนอกเดียว

คุณอาจต้องการทดสอบการปฏิบัติการแต่ละครั้ง ตรวจสอบว่านาฬิกาของระบบให้เวลาที่ถูกต้องตรวจสอบไฟล์จริงจำสิ่งที่ถูกเขียนตรวจสอบอุปกรณ์ที่ได้รับการดำเนินการเดียว ...

การทดสอบเหล่านี้:

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

การทดสอบตรรกะ (รหัสอัลกอริทึม) ที่เชื่อมต่อกันกับการดำเนินการภายนอก

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

คุณสามารถทดสอบเพียงเป็นโครงการปกติใด ๆที่คุณไม่ได้อยู่ในรหัสที่ยากต่อการทดสอบในตัวอีกต่อไป


3

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

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

ระบบการพัฒนาที่ ARM Holdings จัดจำหน่ายให้สำหรับเรื่องนี้และมีแนวโน้มที่จะทำงานได้ง่ายกว่าการแฮ็คข้อมูล QEMU แต่มีราคาแพงมาก

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

คุณสามารถเขียนชุดทดสอบหน่วยเทียมอย่างง่าย ๆ ใน C หรือ C ++ เชื่อมโยงคลาสหรือรูทีนย่อยภายใต้การทดสอบแล้วเรียกใช้มันในโปรแกรมจำลอง

ฉันไตร่ตรองปัญหาที่คล้ายกันมาหลายปีแล้ววิธีทดสอบหน่วย Linux หรือ Mac OS X เคอร์เนลรหัสหน่วย มันควรจะเป็นไปได้ แต่ฉันไม่เคยลองจริง ๆ อาจเป็นไปได้ที่จะสร้างเคอร์เนลแบบเต็มแทนที่จะทดสอบโค้ดของคุณโดยแยกด้วยเฟรมเวิร์กการทดสอบหน่วยที่ลิงก์โดยตรงกับเคอร์เนลของคุณ จากนั้นคุณจะทำการทดสอบหน่วยจากอินเทอร์เฟซภายนอกบางชนิด

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


3

เช่นเดียวกับ TDD แบบไม่ฝังวัตถุจำลองเป็นเพื่อนของคุณอย่างแน่นอน

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

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

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

นอกจากนี้หากการพัฒนาออนไลน์มีค่าใช้จ่ายสูงกว่าการพัฒนาออฟไลน์ (เช่นเดียวกับที่ฉันทำงาน) มันอาจช่วยให้คุณประหยัดเวลาได้มากในการออนไลน์ที่มีชุดทดสอบที่เข้าใจกันดีในการใช้งาน


+1 สำหรับการนำวัตถุจำลองไปวางบนจาน @mark ปัญหาหนึ่งคือการสร้างความมั่นใจในความถูกต้องของวัตถุจำลองซึ่งหมายความว่าการเข้าใจวัตถุที่ถูกเยาะเย้ยน่าจะค่อนข้างลึก สิ่งนี้ดีเพราะบังคับให้ผู้พัฒนาเข้าใจถึงพฤติกรรมของวัตถุภายนอกที่มีการเชื่อมต่อ
tehnyit

1

ในการพัฒนาแบบฝังตัวคุณมักจะทำการสแกนขอบเขตเพื่อตรวจสอบการใช้งานทั้งหมด (รวมถึงฮาร์ดแวร์) ดูที่JTAGสำหรับในการดีบักระบบ

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

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


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