Jalankan tes unit secara lokal di STM32CubeIDE di bawah Windows

Pendahuluan


Semua orang tahu manfaat pengujian unit. Pertama-tama, menulis tes pada saat yang sama dengan kode memungkinkan Anda untuk mendeteksi kesalahan lebih awal dan tidak membuang-buang waktu setelahnya pada debugging rumit yang melelahkan. Dalam kasus pengembangan tertanam, pengujian unit memiliki fitur yang terkait, pertama, dengan fakta bahwa kode berjalan di suatu tempat yang jauh di dalam usus perangkat dan cukup sulit untuk berinteraksi dengannya, dan kedua, kode ini sangat terkait dengan perangkat keras target. .


Jika ada fragmen dalam proyek yang tidak bergantung pada perangkat keras dan pada saat yang sama menerapkan logika yang cukup kompleks, bagi mereka penggunaan unit test akan memberikan manfaat terbesar. Misalnya, itu mungkin implementasi protokol transfer data, berbagai perhitungan, atau mesin negara pengendali.


Ada tiga cara untuk menjalankan tes unit untuk platform tertanam:


  1. Luncurkan langsung pada platform target. Dalam hal ini, Anda dapat bekerja dengan peralatan perangkat, dan kodenya akan bekerja persis sama seperti dalam kondisi pertempuran. Namun, untuk pengujian Anda perlu akses fisik ke perangkat. Selain itu, siklus pengujian akan cukup lama karena kebutuhan untuk terus mengunduh kode ke perangkat.
  2. Berjalan di emulator. Metode ini baik terutama karena memungkinkan Anda untuk bekerja bahkan ketika platform target tidak tersedia (misalnya, karena belum dilakukan). Kerugiannya adalah ketepatan yang terbatas dalam mereproduksi perilaku besi (dan dunia sekitarnya), serta kesulitan membuat emulator semacam itu.
  3. Berjalan di mesin host (lokal). Ini tidak akan bekerja dengan peralatan (Anda dapat menggunakan rintisan uji sebagai gantinya), tetapi tes akan dengan cepat memulai dan bekerja, dan Anda tidak perlu akses ke perangkat target. Contoh yang baik untuk menggunakan metode ini adalah menguji implementasi pada mikrokontroler dari beberapa algoritma komputasi, yang dengan sendirinya tidak tergantung pada perangkat keras, tetapi menggunakan data sensor perangkat. Menguji suatu algoritma dengan sumber data nyata akan sangat merepotkan, jauh lebih baik untuk mencatat pengukuran ini sekali dan menjalankan tes yang sudah ada pada data yang disimpan. Script ini akan menjalankan tes secara lokal dan akan dibahas nanti.

Publikasi ini menyediakan cara untuk mengonfigurasi uji unit di lingkungan STM32CubeIDE, berdasarkan Eclipse dan dimaksudkan untuk pengembangan untuk pengontrol keluarga STM32. Bahasa pengembangan adalah C, tetapi tes itu sendiri ditulis dalam C ++. Tes akan berjalan pada mesin host Windows menggunakan Cygwin. Sebagai kerangka uji, Google Test digunakan. Hasilnya akan ditampilkan di jendela plug-in khusus untuk pengujian unit, dan mereka dapat diluncurkan dengan satu tombol dari proyek untuk STM32:



Metode yang dijelaskan ini cocok untuk lingkungan pengembangan lain berdasarkan Eclipse, kecuali tentu saja produsen yang baik telah memotongnya terlalu banyak demi kenyamanan pengembang. Metode ini juga akan bekerja dengan CubeIDE di Linux, tanpa perlu repot dengan Cygwin.


Anda akan membutuhkannya


  1. Cygwin 3.0.7 x86 (karena tes ini untuk mikrokontroler 32-bit, kami juga akan menggunakan lingkungan 32-bit pada platform 64-bit)
  2. STM32CubeIDE 1.0.2 untuk Windows.
  3. Google Test Framework 1.8.1

Instal Cygwin dan STM32CubeIDE


Cygwin


Instal Cygwin, versi x86. Di installer, pilih paket tambahan: gcc-core, g ++, binutils, automake, autoconf, cmake, libtool, gdb, make. Anda dapat menginstal versi stabil paket terbaru.



Anda juga perlu mendaftarkan variabel lingkungan:


PATH: ...; C: \ <path_to_Cygwin> \ Cygwin \ bin; C: \ <path_to_Cygwin> \ Cygwin \ lib
classpath: C: \ <path_to_Cygwin> \ Cygwin \ lib


STM32CubeIDE


Lingkungan dipasang seperti biasa. Disarankan untuk menginstal CubeIDE setelah Cygwin, karena dalam hal ini Cube akan mengambil toolchain Cygwin yang ada.


Pertama, buat proyek C ++ untuk platform x86 Cygwin. Kita akan membutuhkannya, pertama, untuk memeriksa fungsionalitas toolchain, dan kedua, kita akan menggunakannya sebagai "donor" konfigurasi perakitan untuk proyek utama.


Pilih File> Baru> Proyek C / C ++. Pilih C ++ Build yang Dikelola. Kami membuat proyek bertipe hello world untuk rantai alat Cygwin GCC:



Selanjutnya, Anda harus memilih konfigurasi rakitan mana yang akan dibuat. Hanya Debug sudah cukup.
Sekarang Anda dapat memverifikasi bahwa proyek berjalan dengan memilih Project> Build All. Juga disarankan untuk memeriksa debugging di bawah Cygwin dengan menjalankan Run> Debug As> C / C ++ Aplikasi Lokal. Aplikasi ini akan menampilkan "Hello world" ke konsol di dalam CubeIDE.


Agar debugger menampilkan baris yang dapat dieksekusi dalam file kode sumber, Anda perlu mengonfigurasi tampilan jalur. Di jendela> Preferensi, di tab C / C ++> Debug, pilih Jalur Pencarian Sumber dan tambahkan tampilan baru: Tambah> Pemetaan Jalur. Di jendela, Anda perlu memberi nama sesuatu seperti tampilan baru dan menambahkan baris untuk disk yang ada di sistem:


  • \ cygdrive \ c - C: \
  • \ cygdrive \ g - G: \



Untuk uji coba yang indah, kami juga membutuhkan plug-in untuk Eclipse dengan dukungan untuk tes unit untuk C ++. Itu diinstal langsung dari STM32CubeIDE: menu Bantuan> Instal Perangkat Lunak Baru, lalu pilih Eclipse Repository dan instal plugin C / C ++ Unit Testing.



Bangun Perpustakaan Tes Google


Kode sumber perpustakaan dapat ditemukan di: https://github.com/google/googletest/tree/release-1.8.1
Buka paket sumbernya, buka direktori googletest-release-1.8.1 menggunakan terminal Cygwin, dan jalankan:


cmake . make 

Setelah perakitan berhasil, file perpustakaan statis akan berada di ./googlemock/lib/libgtest.a, dan file header akan berada di direktori ./googletest/include/gtest/ direktori. Mereka perlu disalin ke proyek kami (atau menulis path ke file-file ini dalam pengaturan proyek).


Membuat proyek untuk STM32


Desain untuk papan debug STM32L476G-DISCO. Contohnya tidak akan terlalu canggih - ada dua LED di papan tulis, biarkan mereka menunjukkan penghitung biner dari 00 hingga 11. Kami akan menerapkan modul terpisah untuk penghitung, dijelaskan dalam sepasang file .h dan .c, dan menulis tes untuk itu.
Proyek ini dapat dibuat seperti biasa, menggunakan konfigurator Cube, yang utama adalah memastikan bahwa pin PB2 dan PE8 dikonfigurasi sebagai output digital. Saat membuat proyek, akan lebih baik untuk menentukan jenis - C ++, ini akan diperlukan untuk mengkompilasi tes (kode utama masih akan dikompilasi oleh kompiler C). Mengonversi proyek dari C akan dimungkinkan nanti, dengan mengklik nama proyek RMB dan memilih "Konversikan ke C ++".


Untuk kompilasi di bawah MK dan untuk pengujian kami membutuhkan dua konfigurasi rakitan yang berbeda. Dalam konfigurasi ini, kumpulan file yang berbeda akan dikumpulkan - yang utama akan mendapatkan modul untuk bekerja dengan perangkat keras dan modul yang diuji, dan yang uji akan mendapatkan modul yang diuji dan file uji yang sama. Oleh karena itu, kami akan membuat direktori berbeda di root proyek - Aplikasi dengan kode aplikasi untuk MK (Anda dapat dengan mudah mengganti nama direktori Src yang dibuat Cube), Umum untuk modul yang tidak bergantung pada besi (yang akan kami uji) dan Tes untuk pengujian. Direktori dapat dikecualikan dari majelis dengan mengklik RMB pada namanya, menu Konfigurasi Sumber Daya> Kecualikan dari build.


Tambahkan modul penghitung kami ke direktori Umum:


Kode Led_counter

(led_counter.h):


 #ifndef LED_COUNTER_H_ #define LED_COUNTER_H_ #include <stdint.h> void Led_Counter_Init(); uint8_t Led_Counter_Get_Next(); #endif /* LED_COUNTER_H_ */ 

led_counter.cpp:


 #include "led_counter.h" static uint8_t led_cnt_state = 0; void Led_Counter_Init() { led_cnt_state = 0; } uint8_t Led_Counter_Get_Next() { if(++led_cnt_state > 3) led_cnt_state = 0; return led_cnt_state; } 

Direktori Umum dan Tes harus ditambahkan ke jalur pencarian untuk menyertakan file: properti proyek (Properti)> C / C ++ Umum> Jalur dan Simbol> Termasuk.


Tambahkan untuk bekerja dengan LED utama


Fragmen main.c

main.c:


 /* USER CODE BEGIN Includes */ #include "led_counter.h" /* USER CODE END Includes */ … int main(void) { … /* USER CODE BEGIN WHILE */ Led_Counter_Init(); uint8_t led_state = 0; while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ led_state = Led_Counter_Get_Next(); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, led_state & (1<<0)); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, led_state & (1<<1)); HAL_Delay(500); } /* USER CODE END 3 */ … } 

Proyek harus dikompilasi dan dijalankan, dan LED harus berkedip.


Tes menulis


Sekarang yang semuanya dimulai.


Buat konfigurasi bangunan baru melalui properti proyek - Properti> C / C ++ Build> Pengaturan> Kelola Konfigurasi. CubeIDE tidak akan membiarkan Anda membuat konfigurasi untuk membangun di bawah Cygwin, jadi salinlah dari proyek yang kami buat sebelumnya:



Sekarang Anda perlu beralih ke konfigurasi ini dan mengkonfigurasi jalur ke file sumber dan file header. Dalam properti proyek di tab Paths and Symbols yang kami tentukan (saat menambahkan entri, lebih baik meletakkan daw di bidang "tambahkan ke semua bahasa"):


  • Termasuk - Tes / Inc, Umum / Inc
  • Perpustakaan - gtest
  • Jalur Perpustakaan - Tes / Lib
  • Lokasi Sumber - / <prj_name> / Umum dan / <prj_name> / Tes (ganti <prj_name> dengan nama proyek)

Selanjutnya, salin perpustakaan gtest - file .a ke direktori Tests / Lib ke proyek, dan file header di folder gtest - ke folder Tests / Inc. Di folder Tes, buat file main.cpp baru di mana tes akan dijalankan. Isinya standar:


main.cpp:


 /* * Unit tests main file */ #include "gtest/gtest.h" int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } 

Juga, untuk memeriksa pengaturan, kami akan membuat satu tes yang akan memeriksa bahwa ukuran pointer adalah 32 bit di lingkungan kami (kami ingin memastikan bahwa itu sama seperti pada mikrokontroler, untuk ini kami mengatur 32-bit Cygwin).


Buat file tes test_platform.cpp berikut:


 #include "gtest/gtest.h" TEST(PlatformTest, TestPointerSize) { //Check pointer size is 32 bit ASSERT_EQ(sizeof(void*)*8, 32U); } 

Sekarang, jika proyek dijalankan seperti biasa Aplikasi C ++, hasil debug akan berisi pesan dari Google Test yang menyatakan bahwa semua tes telah lulus.


Struktur proyek akan terlihat seperti ini:


Sekarang kita akan menulis tes untuk modul penghitung LED kita. File pengujian dapat ditemukan di folder Tes:


test_led_counter.cpp
 #include "gtest/gtest.h" extern "C" { #include "led_counter.h" } // Test fixture class LedCounterTest: public ::testing::Test { protected: void SetUp() { Led_Counter_Init(); } }; // Check initial value TEST_F(LedCounterTest, TestInitialValue) { Led_Counter_Init(); ASSERT_EQ(Led_Counter_Get_Next(), 1); } // Check how value is incremented TEST_F(LedCounterTest, TestIncrementValue) { Led_Counter_Init(); unsigned int val = Led_Counter_Get_Next(); for(int i=0;i<1;i++) { ASSERT_EQ(Led_Counter_Get_Next(), ++val); } } // Check how value return to 0 after 3 TEST_F(LedCounterTest, TestZeroCrossing) { Led_Counter_Init(); for(int i=0;i<3;i++) { Led_Counter_Get_Next(); } ASSERT_EQ(Led_Counter_Get_Next(), 0); } 

Agar hasil pengujian ditampilkan di jendela yang indah, Anda perlu membuat konfigurasi peluncuran baru di menu Run> Debug Configurations. Plugin yang diinstal memungkinkan Anda untuk membuat konfigurasi tipe C / C ++ Unit. Buat itu, panggil Jalankan Tes, pilih konfigurasi perakitan "Uji" yang digunakan dan hapus centang pada kotak centang "berhenti saat mulai di" pada tab Debugger. Setelah itu, konfigurasi dapat dimulai.


Untuk jendela dengan hasil yang muncul, pilih di Window> Show View> Other> C / C ++> C / C ++ Unit.



Selesai! Sekarang proyek dapat dikompilasi dan dijalankan di bawah target MK seperti biasa. Ketika Anda perlu menjalankan tes lokal, ketika Anda menjalankan konfigurasi Run Tests, proyek akan secara otomatis dibangun kembali untuk x86, lingkungan akan menjalankan tes dan menunjukkan hasilnya.


Sastra


  1. J. Grenning. Pengembangan Didorong Uji untuk Embedded C. - pekerjaan mendasar pada pengujian unit sistem tertanam dan pada penerapan metodologi TDD.
  2. https://uncannier.com/unit-testing-of-embedded-firmware-part-1-software-confucius/ - Pengujian unit kode mikrokontroler x86 di Texas Composer Studio Code Composer Studio, kerangka CppUTest
  3. http://blog.atollic.com/why-running-your-embedded-arm-cortex-code-on-a-host-pc-is-a-good-thing - sebuah artikel tentang mengapa mungkin berguna untuk menjalankan kode untuk mikrokontroler pada platform desktop

Source: https://habr.com/ru/post/id469367/


All Articles