Unit pengujian efek samping kode berat

10

Saya mulai menulis kode C ++ untuk menjalankan robot, dan saya tidak tahu cara menggabungkan pengujian unit, jika memang saya bisa. Saya telah diberi perpustakaan yang memungkinkan pembuatan "perintah" untuk robot, yang secara otomatis dijadwalkan dan dieksekusi. Mekanisme untuk membuat perintah ini adalah untuk subclass kelas dasar perintah yang mereka berikan, dan melaksanakan maya void Initialize(), void Execute()dan void End()metode. Fungsi-fungsi ini dijalankan murni untuk efek sampingnya, yang melakukan hal-hal pada robot (menjalankan motor, memperpanjang piston, dll.). Karena itu, saya tidak benar-benar melihat di mana pun untuk melampirkan unit test ke kode, singkat mengejek seluruh perpustakaan sehingga saya dapat memeriksa virtual sebelum dan sesudah keadaan robot. Apakah ada cara untuk menguji unit ini yang tidak terlalu memberatkan?

Edit

Saya pikir saya mungkin telah menyesatkan tentang fungsi perpustakaan. Perpustakaan menyediakan sebagian besar antarmuka untuk robot serta sistem perintah / penjadwalan, sehingga tidak sesederhana mengejek kelas basis perintah, saya harus mengejek seluruh antarmuka ke perangkat keras. Sayangnya saya tidak punya waktu untuk melakukan itu.

Will Kunkel
sumber
Saya berasumsi Anda dapat membatalkan tindakan yang Anda lakukan pada robot Anda, bukan? Tidak bisakah Anda membatalkan tindakan tes Anda?
Neil
1
Sayang sekali perpustakaan tidak menggunakan komposisi alih-alih warisan, karena Anda bisa saja mengejek kelas perintah jika itu yang terjadi.
Robert Harvey
@Neil Saya tidak yakin apa yang Anda minta. Bisakah Anda ulangi pertanyaan Anda?
Will Kunkel

Jawaban:

7

Apa yang akan saya lakukan dalam hal ini adalah memperkenalkan antarmuka RobotControl saya sendiri dengan metode yang sesuai dengan yang ada di lib nyata.

Setelah melakukan ini, saya akan membuat kelas RobotControlImpl yang mengimplementasikan antarmuka ini terhadap lib robot nyata.

Perintah yang saya akan tulis tidak akan memperluas kelas dasar, tetapi beroperasi pada antarmuka yang Anda perkenalkan.

Dengan cara ini Anda dapat mengejek RobotControl, meneruskan tiruan itu ke perintah apa pun dan memverifikasi bahwa itu disebut metode yang tepat pada antarmuka.

Dalam prod Anda akan melewati alat nyata dari RobotControl ke perintah yang Anda terapkan.

Saya tidak yakin apakah ini yang ada dalam pikiran Anda dan dianggap tidak praktis?

Sunting: Oh, dan jika Anda mengharapkan perintah untuk tidur untuk menunggu penyelesaian (mimpi buruk, tapi kadang-kadang ini yang Anda miliki), saya akan meminta perintah untuk memanggil metode tidur di RobotControl. Dengan cara ini Anda dapat menonaktifkan tidur selama tes dan memverifikasi bahwa perintah mencoba untuk tidur.

Alexander Torstling
sumber
2
+1. Tidak suka antarmuka? Buatlah milikmu sendiri.
Neil
Ini terdengar seperti Anda menyarankan agar saya mengejek seluruh perpustakaan. Hampir semua fungsi yang akan dipanggil oleh perintah bersifat internal ke perpustakaan.
Will Kunkel
0

Saya pikir mungkin untuk membuat kode dapat diuji dengan cara invasif minimal. Maksud saya adalah bahwa Anda dapat menulis perintah persis seperti yang dimaksudkan oleh penulis perpustakaan robot. Ini bisa menguntungkan jika Anda ingin bertukar kode dengan orang lain yang tidak menggunakan lapisan perantara Anda.

Itu memang membutuhkan "unit test build" terpisah dari kode Anda.

Apa yang Anda lakukan adalah bahwa dalam satu file tajuk pusat, Anda memeriksa waktu kompilasi menentukan apakah ini adalah unit test build, dan jika demikian, mendefinisikan kembali nama kelas dasar, dan mungkin beberapa kelas lain di perpustakaan robot untuk nama-nama kelas implementasi tes Anda. Anda harus mendefinisikan fungsi virtual yang sama seperti pada lib robot, serta memberikan stub untuk metode yang Anda gunakan pada robot.

Kemudian Anda memiliki perintah yang bisa Anda masukkan ke dalam kerangka pengujian Anda sendiri yang menggunakan metode yang sama dengan yang dilakukan perpustakaan robot.

Ini akan melibatkan sejumlah stubbing dan ejekan, tetapi itu tidak bisa dihindari dalam desain unit tes apa pun.

Mengubah nama kelas dasar dapat dilakukan dengan #define atau mungkin lebih disukai, sebuah typedef.

jdv-Jan de Vaan
sumber