Powrót do strony głównej

Testowanie modułowe embedded: zasady

Artykuł analizuje zalety testowania modułowego w rozwoju embedded: kontrola, refaktoryzacja, dokumentacja. Opisano wady z rozwiązaniami i 20 zasad pisania testów, w tym AAA i HIL na target. Nadaje się dla deweloperów firmware middle/senior.

Jak wdrożyć testy modułowe w embedded firmware
Advertisement 728x90

Testy modułowe w embedded: zasady i praktyka

Testy modułowe w firmware dla systemów embedded pozwalają kontrolować poprawność działania kodu, ułatwiają refaktoryzację i dokumentują API. Autor kodu pisze podstawowy zestaw testów, a koledzy dodają niezależne weryfikacje. To szczególnie ważne dla protokołów typu UDS z wymaganiami dotyczącymi DTC.

Zalety wprowadzenia testów modułowych

Testy modułowe to wywołanie funkcji z ustalonymi argumentami i sprawdzenie wyniku, analogicznie do SIL. Rozwiązują kilka problemów:

  • Kontrola funkcjonalności: test potwierdza, że kod działa poprawnie.
  • Bezpieczna refaktoryzacja: zmiany nie psują istniejącego kodu.
  • Dokumentacja: przykłady użycia widać w testach bez zbędnych komentarzy.
  • Kryterium zakończenia: przejście do następnego komponentu dopiero po zaliczeniu testów.
  • Kontrola wykonania: lider może zdefiniować testy do weryfikacji wkładu developera.

Testy zdejmują odpowiedzialność z autora: jeśli kod przeszedł testy wczoraj, problem leży gdzie indziej. Wykrywają nieosiągalny kod przy mierzeniu pokrycia i wymuszają modułową strukturę, unikając spaghetti-kodu z cyklopami i magicznymi liczbami.

Google AdInline article slot

Analogia do PCB: test-pady projektuje się na etapie schematu, nie po lutowaniu. W oprogramowaniu podobnie — pisz małe funkcje od samego początku. Testy gwarantują przenośność na platformy (ARM Cortex-M, RISC-V, PowerPC) i kompilatory (GCC, IAR, Clang). Testy regresyjne łapią błędy w starym kodzie spowodowane nowymi zmianami.

Uruchomienie testów jest darmowe i szybkie, w przeciwieństwie do manualnego testowania z błędami poznawczymi. Dla menedżerów to metryka postępu. Debugowanie ułatwia się: raport testów wskazuje wadliwą funkcję.

Wady i sposoby obejścia

Testy modułowe mają ograniczenia, ale standardowe praktyki je rozwiązują.

Google AdInline article slot
  • Pamięć na testy: na MCU z małym Flash dziel testy na grupy, uruchamiaj sekwencyjnie przez bootloader i CLI. Automatyzuj w CI/CD (Jenkins). Alternatywa — testuj na MCU z większym Flash, kopiuj działający kod.
  • Błędy w testach: rób code-review, pisz testy odporne na awarie.
  • Nadmiarowość: kieruj się pokryciem kodu (narzędzia jak Testwell CTC++) lub wymaganiami technicznymi. Test tylko pod konkretne wymaganie.
  • Nie pokrywają integracji: uzupełniaj testami integracyjnymi. Memy o uTest drzwi w metrze ilustrują: testy jednostkowe nie gwarantują systemu.

Zasady pisania testów modułowych

Autor modułu pisze pierwszy zestaw — zna domenę. Oddzielaj kod i testy w katalogach.

  • Każdy test sprawdza jedną rzecz.
  • Przed fixem buga — napisz test na niego.
  • Determinizm: bez rand(), stałe wejścia.
  • Prostota: krótki, czytelny, na jeden ekran.
  • AAA: Arrange (przygotowanie), Act (działanie), Assert (weryfikacja).
  • Bez if — używaj makr ASSERT.
  • Sprawdzaj edge-case'y.
  • Integracja z CI, uruchamianie przez CLI (UART).
  • Odporność na refaktoryzację.
  • Kolejność testów nie wpływa na wynik.
  • Uruchamianie na target (HIL) przez Shell/Putty.

Testy albo działają, albo je usuń. Naprawa ma priorytet nad kodem produkcyjnym. Obiektywne testy od kolegów wzmacniają pokrycie.

Złożoność systemu testowego może przewyższać produkt, np. przy testowaniu kodeków audio (SGTL5000, MAX9860). Ale dyscyplina zwraca się niezawodnością.

Google AdInline article slot

Co najważniejsze

  • Testy modułowe planuj od początku rozwoju dla modularności i przenośności.
  • Pisz testy sam: głębokie zrozumienie przyspiesza pracę.
  • Używaj AAA i determinizmu dla niezawodności.
  • Uruchamianie na target przez CLI — klucz do HIL.
  • Uzupełniaj testami integracyjnymi dla pełnego obrazu.

— Editorial Team

Advertisement 728x90

Czytaj dalej