Saya mencari beberapa strategi praktik terbaik untuk kode pengujian unit yang ditulis untuk sistem tertanam. Dengan sistem tertanam, maksud saya kode seperti driver perangkat, penangan ISR dll, hal-hal yang cukup dekat dengan logam.
Sebagian besar unit test tidak mungkin dilakukan tanpa mengujinya pada perangkat keras dengan bantuan ICE. Terkadang, unit tertanam juga perlu dihubungkan ke stimulus lain seperti sakelar mekanis, motor stepper, dan bola lampu. Ini biasanya terjadi dalam mode manual, otomatisasi akan bagus tetapi sulit dan mahal untuk dicapai.
Memperbarui
Saya menemukan kerangka kerja pengujian C yang tampaknya cukup berhasil dalam menguji proyek tertanam. Ini menggunakan ide-ide perangkat keras mengejek. Lihat Unity , CMock , dan mungkin Ceedling .
Perbarui 06Jul2016
Datang di cmocka - tampaknya lebih aktif dikerjakan.
sumber
Jawaban:
Saya akan abstrak jauh dari dependensi perangkat keras pada langkah sedini mungkin, dan membangun sistem pada emulasi perangkat lunak / memanfaatkan uji, memungkinkan segala macam kerangka kerja pengujian. Seringkali PC pengembangan saya digunakan untuk menguji sebanyak 95% atau lebih dari sistem yang lengkap. Biaya overhead tambahan (lapisan abstraksi lain) dengan mudah dimenangkan kembali oleh kode pembersih yang dihasilkan sebagai akibat dari abstraksi itu.
Pengujian bagian-bagian yang benar-benar baremetal dari sistem tertanam biasanya merupakan aplikasi terpisah (Uji unit?) Yang memalu firmware jauh melampaui apa yang bahkan dapat dicapai oleh aplikasi. Otomasi dapat dilakukan - dengan biaya, tetapi tidak khas.
Kecuali, yaitu, Anda memiliki anggaran untuk membangun harness perangkat keras unit test termasuk ICE lengkap. Ini benar-benar baik karena umumnya tes fungsional kecil.
sumber
Alat yang diperlukan untuk dikembangkan adalah injektor sinyal. Sistem tertanam akan memiliki beberapa cara untuk berinteraksi dengan sistem host (biasanya melalui port serial yang disediakan untuk debugging). Gunakan ini untuk mengirim data uji (opsi terbaik adalah singkat ascii diformat sehingga mudah disimulasikan oleh manusia juga).
Saya sepenuhnya tidak setuju dengan bagian dari pertanyaan Anda ini: "otomasi akan bagus tetapi sulit dan mahal untuk dicapai."
Menggunakan TeraTerm sebagai injektor sinyal port serial, dan menulis beberapa makro TeraTerm (membutuhkan waktu sekitar 20 menit), ada serangkaian besar tes otomatis yang dapat dijalankan terhadap bagian mana pun dari sistem tertanam - apakah lapisan driver, O / S, layer 4-5, dll. TeraTerm: http://en.sourceforge.jp/projects/ttssh2/
Jika port serial tidak tersedia pada sistem tertanam, maka gunakan alat perangkat keras untuk mengubah data port USB / serial menjadi sinyal digital (juga murah dan mudah dicapai). Ketika Anda membaca ini, saya menggunakan papan mikrokontroler $ 30 (UBW: http://www.schmalzhaus.com/UBW32/ ) untuk menguji sistem tertanam untuk produksi, dengan menyuntikkan stimulus melalui makro TeraTerm yang dikirim melalui USB / serial ke mikrokontroler, yang menjalankan firmware yang dimodifikasi yang menjalankan input digital dan memonitor output digital dari sistem target yang disematkan. Sehubungan dengan ini, kami mengembangkan skrip python (menggunakan pyserial dan pexpect) untuk mengotomatisasi injeksi data dan validasi data. Tidak ada yang sulit dan tidak ada yang mahal. Dalam pengalaman saya, para manajer menghabiskan banyak uang (seperti $ 30.000 alat uji) ketika tim uji tidak berpengalaman dan tidak dapat memahami solusi mudah ini - sayangnya, tujuan umum peralatan besi besar sering tidak termasuk kasus uji yang menangkap waktu terburuk / etc dari sistem target. Jadi metode yang murah lebih disukai untuk cakupan tes. Percaya atau tidak.
sumber
Ini adalah masalah yang sangat sulit.
Saya sebenarnya telah merancang unit harness pengujian untuk sistem tertanam, yang akan memungkinkan simulasi acara perangkat keras / interupsi, dan mengontrol waktu pelaksanaan (untuk memastikan kami mencakup semua kemungkinan interleavings karena konkurensi), dan butuh tim dari programmer lebih dari 2 tahun untuk benar-benar mengimplementasikannya dan membuatnya bekerja. Proyek itu adalah pengembangan hak milik, tetapi proyek serupa (lebih sederhana dalam desain) tersedia di sini .
Jadi ya, otomatisasi akan bagus. Ya, itu sangat sulit dan mahal untuk dicapai. Ya, terkadang Anda harus melakukan itu. Meskipun jarang, dalam pengalaman saya dalam banyak kasus, lebih cepat dan lebih murah untuk menggunakan motor stepper dan bola lampu dan membuatnya semuanya bekerja secara manual.
sumber
Sunting: jawaban saya dekat dengan mattnz, saya pikir ...
Saya ingin mengaitkan masalah ini dengan orang lain, semua tes yang bergantung pada sesuatu di luar kode Anda (seperti jam sistem, sistem file persisten atau database, menghubungi layanan web eksternal ...). Saya menyarankan kebijakan yang sama untuk mereka semua, mengisolasi dua level dalam dua lapisan kode.
Menguji operasi eksternal tunggal
Anda mungkin ingin menguji secara fisik setiap operasi. Periksa apakah jam sistem memberikan waktu yang tepat, periksa file yang benar-benar mengingat apa yang telah ditulis, periksa perangkat yang menerima satu operasi ...
Tes-tes ini:
Menguji logika (kode, algoritma) yang menghubungkan operasi eksternal
Dengan memiliki lapisan kode untuk membuat operasi eksternal yang sebenarnya, dengan menyembunyikannya dari antarmuka yang dapat Anda tiru dengan mudah, logika Anda tidak lagi bergantung pada perangkat fisik yang sebenarnya ...
Anda dapat menguji secara sederhana, seperti proyek biasa, Anda tidak lagi berada dalam kode sulit-untuk-uji yang tertanam .
sumber
Simulator CPU tertanam umumnya dapat diprogram untuk juga mensimulasikan perangkat keras. Semua teknologi virtualisasi selain Xen melakukan itu. Tetapi Anda perlu menulis kode yang berpura-pura memiliki beberapa register di beberapa alamat fisik atau, pada x86, alamat pada bus I / O, dan kemudian Anda perlu merespons membaca dan menulis ke alamat-alamat ini seolah-olah perangkat lunak Anda adalah fisik. chip yang kontrol dan status registernya sedang diakses.
Jika Anda ingin melakukan ini, saya akan menyarankan memodifikasi QEMU. Tapi itu tidak mudah. Hal semacam ini umumnya hanya dilakukan ketika Anda merancang chip khusus dengan mikrokontroler dan beberapa core lainnya untuk I / O Anda.
Sistem pengembangan yang dijual oleh ARM Holdings menyediakan ini dan kemungkinan lebih mudah untuk dikerjakan daripada meretas QEMU, tetapi sangat mahal.
Ada beberapa emulator ARM Open Source yang menjalankan subrutin tunggal, yang dengan sendirinya dapat memanggil subrutin lain, yang dapat Anda gunakan untuk debugging tuning kinerja subrutin yang tidak bergantung pada akses perangkat keras. Saya menggunakan salah satu dari ini untuk sukses besar untuk mengoptimalkan enkripsi AES untuk ARM7TDMI.
Anda bisa menulis unit test harness sederhana dalam C atau C ++, menghubungkan kelas atau subrutin yang sedang diuji, lalu menjalankannya di simulator.
Saya telah merenungkan masalah yang sama selama bertahun-tahun, bagaimana unit menguji Linux atau kode kernel Mac OS X. Seharusnya mungkin, tetapi saya belum pernah benar-benar mencobanya. Salah satunya adalah membangun kernel penuh daripada menguji kode Anda secara terpisah, dengan kerangka kerja unit test yang terhubung langsung ke kernel Anda. Anda kemudian akan mematikan tes unit dari beberapa jenis antarmuka eksternal.
Mungkin akan lebih produktif untuk menggunakan alat jangkauan kode, kemudian menguji firmware Anda sebagai paket lengkap melalui antarmuka eksternal. Alat jangkauan akan menemukan jalur kode yang belum diuji, sehingga Anda kemudian dapat menambahkan tes eksternal tambahan dalam upaya untuk mendapatkan lebih banyak cakupan.
sumber
Seperti halnya TDD yang tidak tertanam, objek tiruan sudah pasti adalah teman Anda.
Menjaga antarmuka ke perangkat keras dasar Anda bersih dan sederhana sehingga segala sesuatu di atas level terendah dapat diejek dan Anda akan memiliki waktu yang jauh lebih mudah - jika Anda merancang aplikasi yang tertanam dengan mudah diingat maka pengujian akan selalu berjalan jauh lebih lancar .
Juga, hanya karena Anda mungkin tidak dapat menguji on-line sampai sangat terlambat dalam proyek tidak berarti bahwa Anda tidak harus menyiapkan serangkaian tes on-line juga.
Ini seharusnya (awalnya) hanya perlu menguji bit yang tidak dapat diuji secara offline. Tentu, ini bukan TDD (karena Anda membuat tes di muka) tetapi pengembangan TDD offline Anda akan memberi Anda ide yang bagus tentang seperti apa tampilan antarmuka perangkat keras Anda dan dengan demikian tes online apa yang perlu Anda lakukan.
Juga, jika pengembangan online lebih mahal daripada pengembangan offline (seperti halnya di tempat saya bekerja) maka itu bisa menghemat banyak waktu online dengan memiliki serangkaian tes yang dipahami dengan baik untuk dijalankan.
sumber
Dalam pengembangan tertanam Anda sering melakukan pemindaian batas untuk memverifikasi seluruh aplikasi (termasuk perangkat keras) berfungsi. Lihat juga JTAG untuk debugging sistem.
Menguji rutinitas perangkat lunak murni tanpa tautan ke perangkat keras dapat dilakukan dengan kerangka kerja Uji Unit C standar seperti Periksa . Namun waspadalah terhadap keterbatasan memori (terutama stackspace dll pada perangkat kecil). Ketahui kontrak Anda! Anda juga dapat mencoba untuk mengabstraksikan rutin perangkat lunak dari perangkat keras untuk mendapatkan cakupan uji yang lebih besar tetapi ini biasanya mahal dalam hal kinerja pada perangkat yang disematkan seperti PIC kecil atau AVR. Namun, Anda dapat mengejek port perangkat keras untuk mencapai cakupan yang lebih besar (dan tentu saja Anda dapat menguji tiruan itu juga).
Anda juga dapat mencoba menggunakan emulator untuk chip atau rangkaian simluator, tetapi alat semacam ini mahal (terutama dalam kombinasi) dan rumit.
sumber