Forum: Mikrocontroller und Digitale Elektronik embedded Unit-Tests


von A. B. (funky)


Lesenswert?

Hallo,

hat sich der ein oder andere hier schon mit Unit Tests auf embedded 
Systemen auseinandergesetzt und kann herangehensweisen bzw. Erfahrungen 
zum Besten geben?

Ich habe das bisher nur auf Desktopebene ausprobiert und muss sagen, das 
es schon sinnvoll ist, auch wenn es erstmal Arbeit und eine andere 
Arbeitsweise verlangt.

Ich frage mich nun, wie man das sinnvoll auch im embedded Bereich 
umsetzen könnte? Wenn für Kontroller entwickelt, für welche ein 
Simulator verfügbar ist, so ist das sicherlich einfacher umzusetzen. 
Aber wenn es das nicht gibt? Die Ausgabemöglichkeiten auf dem embedded 
System sind ja doch ziemlich beschränkt.

Hat sich jemand schon näher damit beschäftigt und kann Tips geben?

von Steel (Gast)


Lesenswert?

Mit beschränkten Ausgabemöglichkeiten hat das nichts zu tun. Was es auf 
einem Embedded-System schwierig macht sind die Schnittstellen der Units, 
die nicht selten eben Hardware sind.
Sinn macht es trotzdem, eben nur für bestimmte Module.

von A. B. (funky)


Lesenswert?

naja, ok nur für bestimmte module...trotzdem wäre eine herangehensweise 
ineressant

von Gerhard (Gast)


Lesenswert?

1
int komplizierte_berechnung(int a, int b)
2
{
3
  int z;
4
  // komplizierte berechnung mit a, b, z
5
  return z;
6
}
1
int test_komplizierte_berechnung(void)
2
{
3
  int error_count = 0;
4
5
  if (komplizierte_berechnung(0, 0) != 23) error_count++;
6
  if (komplizierte_berechnung(-1, 0) != 42) error_count++;
7
  if (komplizierte_berechnung(0, -1) != 4711) error_count++;
8
  if (komplizierte_berechnung(30000, -30000) != 666) error_count++;
9
  if (komplizierte_berechnung(1, 1) != 0815) error_count++;
10
  if (komplizierte_berechnung(-1, -1) != 1234) error_count++;
11
  if (komplizierte_berechnung(-30000, 30000) != 4321) error_count++;
12
13
  if (error_count == 0)
14
    usart_puts("komplizierte_berechnung ok\r\n");
15
  else
16
    usart_puts("komplizierte_berechnung kaputt\r\n");
17
}
1
#ifdef TEST
2
int main(void)
3
{
4
  usart_init();
5
  test_komplizierte_berechnung();
6
  //test_anderen_kram1();
7
  //test_anderen_kram2();
8
  //test_anderen_kram3();
9
  //test_anderen_kram4();
10
  return(0);
11
}
12
#else
13
int main(void)
14
{
15
  hw_init();
16
  eeprom_read_config();
17
  while (1 == 1)
18
  {
19
    //main loop
20
  }
21
  return(0);
22
}
23
#endif

von Fauler Tester (Gast)


Lesenswert?

Hi,
gibts eigentlich Programmen die anhand der Funktion
'int komplizierte_berechnung(int a, int b) {..'
ein
'int test_komplizierte_berechnung(void) {..'

automatisch erstellen?

von Noname (Gast)


Lesenswert?

>Hi,
>gibts eigentlich Programmen die anhand der Funktion
>'int komplizierte_berechnung(int a, int b) {..'
>ein
>'int test_komplizierte_berechnung(void) {..'

>automatisch erstellen?

Wenn Du es schreibst, schon.
Aber dieses zweite Programm zu testen, dürfte um einige Grössenordnungen 
komplexer sein, als das ursprüngliche Programm zu testen.

Wenn es sowas zu kaufen gibt, wird es wohl in der Grössenordnung von 
einigen Hunderttausenden liegen, denke ich.

von A. B. (funky)


Lesenswert?

danke schon mal. hab noch ein wenig gestöbert:

http://www.hitex.com/index.php?id=tessy-white-papers&L=2

http://www.amazon.de/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X 
Das Buch habe ich mir mal bestellt. Mal schauen ob das nützliche Infos 
liefert.

von keinLichtAufGing (Gast)


Lesenswert?

>gibts eigentlich Programmen die anhand der Funktion
>'int komplizierte_berechnung(int a, int b) {..'
>ein
>'int test_komplizierte_berechnung(void) {..'

grundsätzlich gibt es so etwas schon (zum Bleistift Quicktest für
Haskell), aber für Embedded kenne ich da nichts "von der Stange".
Ein wichtiges Problem ist: Wie soll "test_komplizierte_berechnung"
wissen, was komplizierte_berechnung(a, b) eigentlich berechnen soll?

von abc (Gast)


Lesenswert?

Moin

erstmal, kannst du den junit test auch mit nem anderen compiler und z.B. 
auf dem PC machen. viele funktionen haben gar keinen HW zugriff, 
auserdem ist der HW zugriff im unit test auch sicher schwerer zu 
bewerkstelligen. Die register sind ja alle input quellen, die bedatet 
werden müssen um ein entsprechendes ergebniss zu erhalten.

Hat natürlich den nachteil, das nicht der Orgnial compiler verwendet 
wird, und der test auf einer anderen MCU ausgeführt wird. Ist dafür aber 
sicher im welten schneller.

In verbindung mit einem Simulator. geht das dann schon richtung auf der 
HW. nur ist der simulator nicht umbedingt deine Orginal HW. 
Laufzeitverhalten von RAM, ... können a bweichen.

Oder auf der ziehl HW. da kommt es drauf an welches tool und welche HW 
du im einsatz hast. auf nem PIC wirds vermutlich gar nix. auf nem cortex 
A8 mit 512MB ram ein kinderspiel. und irgendwo dazwischen fängts dann an 
das manche tools aufgrund der zur verfügung stehenden resourcen 
aussteichgen. zuwenig ram zuwenig flasch. Tessy z.B. generiert für jeden 
TEstfall ein eigenes Programm / je funktion die getestet werden soll, 
schiebt das in den controller, führt es aus und holt dann über den 
debuger die ergebnisse wieder aus dem speicher ab.

Andere Tools brauchen für Ihr framework eine zusätzliche schnittstelle 
über die Testdaten und ergebnisse mit der Zeihlhw ausgetauscht werden.

Für die Testabdeckung / Codeabdekung, muss eigentlich der 
Programmverlauf aufgezeichnet werden. Die einen machen das durch 
"Instrumentierung", in dem sie an jeder stelle im Code an der eine 
VErzweigung auftritt, zusätzliche aufrufe einbauen. Verändert natürlich 
das Laufzeitverhalten. und die Programmgrösse. Mit einem Simulator kann 
das dann in verbindung mit dem Trace nachträglich erledigt werden. 
Welche addressen .

Tools die mit einem Simulator arbeiten müssen teilweise auch nicht den C 
code Instrumentieren. sie gehen über den Object code und schnteiden 
quasi die zu testenden funktion aus, / setzen den Programm counter, 
stack, variablen und regsiter entsptechend.

bist eigentlich 2 wochen zu späht drann. auf der Embedded waren zimlich 
vile vertreten die sich mit test auseinander setzen.

von mthomas (Gast)


Lesenswert?

"Herangehensweise" bei Attolic TrueVerifier ist ganz interessant - wobei 
es sicher noch irgendwo andere Anbieter mit ähnlichem Ansatz gibt.

von A. B. (funky)


Lesenswert?

Ich habe mir spasseshalber mal Tessy von Hitex bzw Razorcat 
angeschaut...sieht interessant aus. Aber den Preis davon will ich lieber 
nicht wissen.

Ich arbeite nun das Buch "Test Driven Development for Embedded C"durch 
und teste gerade http://www.cpputest.org/
Kann das ganze aber noch nicht so einschätzen....braucht noch ein wenig 
Zeit

Mittlerweile funktionieren auch meine printf() Funktionen, so das ich 
das auch auf der Zielhardware direkt laufen lassen kann(STM32)

Behelfsmässig habe ich bei einem anderen Projekt für einen PsOC mal 
meine Sourcen in eine Visual C Project eingebunden und mir dann Ausgabe 
etc drumherumgestrickt. Zum Algorithmentesten hat das gut 
funktioniert...auf dem PsOC hat man nur beschränkte Debugmöglichkeiten, 
und nur per LED Ausgabe oder ähnlichem zu testen ist auf Dauer nicht 
gerade praktikabel

Kleine Funktionen zu testen funktioniert schon gut...wie man aber 
komplette Projekte damit abarbeitet ist noch ein grosses Fragezeichen. 
Wobei man dann ja auch anders arbeitet und die Tests während der 
Entwicklung schreibt. Im Nachhinein die Tests auf ein bestehendes 
Projekt aufzupropfen ist eine Heidenarbeit

von Anja (Gast)


Lesenswert?

A. B. schrieb:
> Die Ausgabemöglichkeiten auf dem embedded
> System sind ja doch ziemlich beschränkt.

In der Regel hast Du:
- Einen InCirquit-Emulator mit dem du (zur Laufzeit) Variablen abfragen 
kannst

oder

- ein Monitor-Programm über die serielle Schnittstelle oder über CAN 
oder über Ethernet.

Bei ganz kleinen Systemen reicht es eventuell alle wichtigen Variablen 
zyklisch über eine LED im Timer-Interrupt herauszutakten.

Gruß Anja

von Purzel H. (hacky)


Lesenswert?

In der Regel hat mankeinen in-circuit emulator, sondern allenfalls einen 
freien pin. Wenn man debugging in die Planung einbezieht, hat man 
wahrscheinlich das Uart und einen steckbaren DAC. Inden meisen faellen 
hat man auch Echtzeitanforderungen, dh man kann keinen Breakpoint haben, 
da sonst der Prozess zerstoert wird. Der Prozess ist zB eine externe 
Differentialgleichung, die abspult. Wenn man einen Breakpoint auf den 
ersten Character einer seriellen Nachricht setzt, empfaengt man den Rest 
der Mldung nicht mehr, und die Antwort geht auch nichtzur Zeit raus. 
Falls das unterbrechen des Prozesses zu Schaden fuehren kann, muss man 
den externen Prozess simulieren.

von abc (Gast)


Lesenswert?

der Unit test hat keine Probleme mit brake points, da es hier nicht auf 
laufzeit ankommt. es wird funktion für funktion getestet. alle input 
variablen werden vorgegeben, das ergebniss wird überprüft. Subfunktionen 
werden wenn notwendig simuliert.

von A. B. (funky)


Lesenswert?

und nicht jeder steuert mit seinem uC Atomreaktoren, Motoren oder 
Zentrifugen ;)

von Thomas (Gast)


Lesenswert?

Fauler Tester schrieb:
> Hi,
> gibts eigentlich Programmen die anhand der Funktion
> 'int komplizierte_berechnung(int a, int b) {..'
> ein
> 'int test_komplizierte_berechnung(void) {..'
>
> automatisch erstellen?
>
C parsen ist keine triviale Angelegenheit, aber dafür gibt es ja die 
ganzen fertigen Frameworks wie GCC und LLVM/Clang. Sowas kann man als 
Plugin für diese schreiben. Dann ist die Ausgabe halt nicht eine 
Objektdatei, sondern eine C-Datei mit deinen test_*-Funktionen.

Oder man nimmt z.B. Doxygen um die Funktionsnamen zu bekommen. Sowas zu 
bauen ist kein großes Problem, wenn man einen fertigen und 
praxiserprobten Parser nimmt. Aber am Ende wirst du es doch nicht 
benutzen wollen, weil es nicht flexibel genug ist. Was machst du z.B. 
wenn du eine Funktion nicht testen willst? Dann bräuchtest du ja einen 
weg um das anzugeben und dann hast du schon wieder so viel Aufwand, dass 
du mit dem händischen Aufschreiben schneller bist.

Wie wäre es z.B. mit einem Macro in deinem Editor, das Automatisch zwei 
Funktionen erstellt? Das scheint mir am sinnvollsten und praktisch alle 
mordernen Editoren haben sehr mächtige Template-Systeme um sowas 
umzusetzen.

von keinLichtAufGing (Gast)


Lesenswert?

Zur Analyse des Quelltextes könnte man noch Frama-C benutzen, die
Value-Analysis liefert dann (manchmal) die möglichen Wertebereiche
der Variablen/Parameter gleich mit. Zum Generieren der Unittests
könnte man dann einfach ein Plugin einbauen.
Für die meisten Anwendungen dürfte das aber Overkill sein.

von TobiasW (Gast)


Lesenswert?

Hallo, ich lese gerade den Beitrag hier und nebenbei auch schon seit ein 
paar Tagen das hier angesprochene "Test-Driven-Development [..]" Buch.

Ich wäre interessiert an euren Erfahrungen mit den besprochenen 
Test-Möglichkeiten (im Target und außerhalb).

Was ist praktikabel, was nicht oder nur bei umfassenden Projekten.

Was sagt ihr zum Thema Test-Driven-Development im embedded Bereich, ggf. 
zum Buch ?

Ich hoffe ich höre von euch ... Danke

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.