Bagaimana cara menulis unit test untuk robot (dan perangkat mekanis lainnya)?

22

Saya anggota klub robotika sekolah menengah saya, dan saya bertanggung jawab untuk pemrograman robot. Satu saran yang saya dengar dari berbagai orang dewasa adalah saya harus menulis unit test untuk membantu memvalidasi kode saya. Basis kode menjadi agak besar, dan saya setuju bahwa tes unit akan sangat membantu dalam membantu saya menangkap bug lebih cepat.

Namun, saya tidak sepenuhnya yakin bagaimana saya bisa mencapai ini. Sepengetahuan saya, pengujian unit dilakukan dengan mengambil fungsi (atau subsistem kode) dan mengumpankannya satu set input untuk memastikan keluar dengan output yang sama setiap kali. Kode yang saya miliki saat ini tidak menghasilkan data yang banyak, tetapi secara langsung memanipulasi komponen perangkat keras pada robot. Sebagian besar kerumitan berasal dari memastikan bahwa elektroniknya sehat, bahwa kode saat ini cocok dengan perangkat keras yang sebenarnya pada robot, dll. Sering kali, saya hanya dapat melihat apakah ada masalah dengan memuat kode ke robot itu sendiri, dan berusaha menjalankannya.

Dengan ekstensi, bagaimana unit test dapat ditulis untuk kode yang dimaksudkan untuk mengoperasikan perangkat mekanis apa pun? Sepertinya saya bahwa Anda hanya dapat menangkap kesalahan dengan mengamati secara fisik pengoperasian mesin.

Atau apakah saya hanya salah paham bagaimana unit test seharusnya bekerja?

( Jika itu penting, ini kodenya , ditulis dalam C ++, dan saya berpartisipasi dalam FRC )

Michael0x2a
sumber

Jawaban:

21

Anda perlu mengejek lapisan perangkat keras untuk melakukan pengujian ini. Idenya adalah bahwa alih-alih kode Anda berbicara dengan perangkat keras yang sebenarnya, Anda berbicara dengan versi perangkat keras palsu yang dapat Anda kontrol dan kemudian gunakan untuk memverifikasi bahwa kode Anda berfungsi dengan benar.

Sayangnya ada beberapa masalah yang harus Anda atasi:

  • Mengejek hal-hal dalam bahasa tingkat rendah lebih sulit (dan dengan demikian, lebih banyak pekerjaan)
  • Mengejek hal-hal tingkat hardware lebih sulit (dan dengan demikian, lebih banyak pekerjaan)

Selain itu, sebagian besar nilai pengujian unit otomatis berasal dari kemampuan menjalankan pengujian Anda kapan saja untuk menangkap bug regresi untuk jangka waktu yang lama setelah Anda menulis kode asli. Dengan kompetisi semacam ini, kode Anda tidak akan digunakan sama sekali setelah kontes selesai, sehingga Anda tidak akan benar-benar mendapatkan sebagian besar nilai dari tes. Dan mengingat betapa sulitnya untuk menambahkan tes ke kasus khusus Anda, mungkin lebih baik menggunakan waktu Anda untuk hanya melakukan pengujian manual dan fokus pada fitur untuk kontes.

Oleksi
sumber
1
Jawaban bagus. Terutama sedikit tentang fakta bahwa kode tidak akan digunakan setelah kompetisi, dan bahwa manfaat besar dari tes unit otomatis muncul setelah tes telah ditulis. Anda mungkin mempertimbangkan untuk mengotomatisasi beberapa tes Anda dalam kasus di mana Anda menemukan diri Anda menjalankan tes yang sama berulang-ulang; tetapi sampai ini terjadi, tidak ada gunanya.
Dawood mengatakan mengembalikan Monica
Tidak perlu Mock perangkat keras sama sekali. Jika robot memiliki logging, jalankan program tes dan amati log. Tes akhir perlu observasi "belok kiri" di log harus sesuai dengan robot belok kiri. Anda perlu menulis test harness untuk mengolok-olok perangkat input - kaitkan kode perangkat input sedekat mungkin ke lapisan perangkat keras
mattnz
4
@ Davidvidallall Sebagai makanan kecil untuk dipikirkan, ketika menggunakan TDD / BDD, manfaat dari pengujian unit terjadi segera. Pertama-tama dengan memungkinkan kode untuk dengan penuh percaya diri direaktor ulang segera, dan kedua dengan mendorong implementasi dibatasi pada implementasi minimum yang diperlukan untuk memenuhi pengujian.
S.Robins
4
@ mattnz ide buruk, dan saya tahu dari pengalaman. Bagaimana jika kode yang diuji gagal sangat keras dan robotarm menabrak dinding, merusak perangkat keras $ xxxx ???
stijn
2
@ mattnz: Robot kami sekitar 2 kaki kali 3 kaki kali 4 kaki, dan beratnya sekitar 150 pound. Kit / biaya pendaftaran 5 ribu dolar setiap tahun, dan kami biasanya menggalang dana 5 hingga 10 ribu lagi untuk membeli suku cadang tambahan. Skenario kasus terburuk mungkin akan menelan biaya lebih dari $ 10;)
Michael0x2a
10

Saya dapat memikirkan beberapa hal yang perlu Anda pertimbangkan. Yang pertama adalah membuat lapisan akses perangkat keras Anda setipis yang Anda bisa, bahkan jika itu berarti membuat lapisan pembungkus-tipe dasar untuknya. Ini menawarkan Anda beberapa keuntungan. Yang pertama adalah memungkinkan Anda mengisolasi perilaku spesifik perangkat keras dari kode Anda dari akses perangkat keras itu sendiri, yang berarti Anda dapat menguji semuanya hingga ke bagian paling bawah perangkat keras Anda tanpa perlu mengakses perangkat keras itu sendiri.

Misalnya, jika Anda perlu merancang protokol pensinyalan berbasis I2C, Anda dapat menguji kode Anda menghasilkan sinyal I2C yang benar tanpa perlu menghubungkan perangkat keras ke dalam pengujian Anda.

Untuk panggilan ke perangkat keras yang sebenarnya, Anda dapat menguji apakah mereka berperilaku dengan benar dengan mengolok-olok lapisan perangkat keras Anda, dan di sinilah menjaga lapisan perangkat keras yang sangat tipis benar-benar terbayar, karena Anda dapat mengurangi tiruan Anda sehingga hanya perlu menangani fungsi minimum yang diperlukan untuk sebenarnya membahas perangkat keras, tetapi Anda tidak perlu menguji masing-masing sinyal itu sendiri, karena semua pensinyalan Anda seharusnya dapat diuji pada tingkat yang lebih tinggi. Ini berarti kemudian Anda menggunakan tiruan Anda untuk memeriksa apakah panggilan dilakukan ke metode perangkat keras tertentu yang menyebabkan sinyal Anda dikirim ke perangkat keras. Jika Anda perlu menyurvei perangkat keras Anda, maka tiruan Anda harus dapat memicu peristiwa atau metode hanya dalam kode Anda, karena sekali lagi, pensinyalan pengembalian Anda harus ditangani di lapisan yang lebih tinggi.

Ini pada dasarnya cocok dengan apa yang dikatakan Oleksi dalam jawabannya , karena biasanya lebih banyak pekerjaan untuk mempermainkan hal-hal tingkat perangkat keras, namun tidak begitu sulit jika Anda tetap menggunakan lapisan kode / panggilan seminimal mungkin yang dapat Anda buat untuk perangkat keras.

Ketika Anda memiliki kode yang lolos dari semua pengujiannya, Anda masih perlu menjalankan serangkaian tes manual untuk memastikan Anda membungkuk semuanya dengan benar di lapisan perangkat keras Anda.

Hal lain yang terlintas dalam pikiran selain dari cemoohan dan pelapisan, adalah menggunakan latihan pengembangan yang pertama. Pada dasarnya, Anda mengkode persyaratan Anda sebagai kriteria pengujian, dan Anda mendasarkan implementasi Anda dari pengujian Anda. Ini akan membantu Anda untuk memastikan Anda menjaga kode implementasi Anda ke minimum, sambil memastikan semua kasus pengujian Anda mendorong upaya pengembangan Anda. Dengan tidak membuang terlalu banyak waktu pada kode lain yang berpotensi tidak penting yang mungkin membuat Anda tergoda untuk melakukan "hanya karena", tes pertama membantu Anda untuk tetap fokus, dan akan membuatnya lebih mudah untuk mengubah kode Anda saat Anda debug, seperti halnya penggunaan unit test dan ejekan Anda. Men-debug bug perangkat lunak melalui perangkat keras sangat rumit dan menyedot banyak waktu Anda sehingga Anda akan menemukan lebih baik dihabiskan untuk tugas-tugas lain.

S.Robins
sumber
2

Saya bisa memberi tahu Anda bagaimana mereka melakukannya di Flight Simulator

Pertama, Anda hanya akan mendapatkan setengah dari jawaban jika Anda mengajukan pertanyaan ini hanya kepada pemrogram sehingga Anda mungkin harus memposting ini di http://electronics.stackexchange.com saat Anda sedang mengerjakannya.

Saya belum melakukan pekerjaan dengan robot tetapi saya menghabiskan 5 tahun melakukan perangkat keras pada simulator penerbangan sehingga saya dapat memberi tahu Anda bagaimana arsitektur mereka bekerja.

Lapisan perangkat kerasnya bodoh

Ini berisi antarmuka dasar di mana Anda dapat menyesuaikan nilai input / output sederhana dan mengatur breakpoint interpolasi untuk sinyal analog. Ketika Anda bekerja dengan perangkat keras 'segar', semuanya akan berfungsi seperti yang diharapkan dengan sedikit atau tanpa kalibrasi, tetapi seiring waktu komponen akan mengalami keausan mekanis dan perlu disesuaikan.

Kalibrasi adalah tabel sederhana yang berisi bagian yang dipotong berkisar antara nilai min / maks. Untuk mengukur input ini, servo biasanya digunakan (ex potensiometer linier, transduser, akselerometer, dll). Atau dalam hal instrumentasi, Anda cukup menilai akurasi secara visual dan menyesuaikan hingga dikalibrasi.

Lapisan perangkat lunak adalah kebalikannya

Semuanya kompleks dan saling berhubungan sehingga penting untuk mengisolasi beberapa variabel untuk menguji fungsionalitasnya. Tidak perlu membuat diri Anda pusing memikirkan skenario karena jauh lebih mudah untuk menjalankan beberapa skenario realistis di mana Anda dapat mengumpulkan data. Ketika Anda menjalankan tes, Anda pada dasarnya mengukur data yang disimpan terhadap output saat ini.

Pada simulator penerbangan, ini disebut sebagai QTG (Panduan Uji Kualifikasi). Pada intinya ia memplot data pada grid 2D di mana satu dimensi adalah waktu dan yang lainnya adalah output.

Percaya atau tidak, itulah esensi dari bagaimana mereka mengembangkan model. Sebuah pesawat nyata dilengkapi dengan satu ton sensor dan diterbangkan melakukan skenario terkontrol. Karena semua kontrol dapat didorong tanpa interaksi manusia, tes dijalankan (yaitu sim itu sendiri) oleh komputer dan data dibandingkan.

Meskipun robot dibuat dalam skala yang jauh berbeda, prinsip-prinsipnya sama. Pendekatan tradisional adalah untuk sepenuhnya memotong lapisan perangkat keras dan perangkat lunak sehingga keduanya dapat diuji secara individual. Input perangkat keras dikumpulkan melalui servos, dan diatur melalui antarmuka independen. Input perangkat lunak dapat diatur / dibaca dengan secara independen mengukur dan membandingkan pensinyalan yang seharusnya masuk ke perangkat keras dan merencanakannya terhadap data 'baik' yang diketahui.

Tes itu sendiri tidak perlu menjadi rumit selama hasilnya dapat diprediksi, diukur, dan dapat diproduksi ulang.

Evan Plaice
sumber
1

Seperti yang dikatakan sebelumnya, mengejek dan mematikan bagian perangkat keras. Sebagai contoh, jika Anda memiliki antarmuka ke robot, Anda dapat mewarisi dari antarmuka itu, dan kemudian membuat implementasi rintisan sederhana itu. Kemudian Anda dapat memiliki tes bahwa implementasi rintisan telah dipanggil seperti yang diharapkan. Jika itu fungsi yang diharapkan atau parameter yang diharapkan.

martiert
sumber