Forum: PC-Programmierung wie statische funktionen im unittest testen


von Lars (Gast)


Lesenswert?

Guten morgen,
wie geht ihr bei Unittests mit statischen funktionen um?
Testet ihr diese? Ich bin gerade mit cmocka gestartet und möchte 
Unittests für mein Projekt erstellen.

Das Problem ist ja, dass diese Funktion aus einer anderen Datei (test.c) 
aufgerufen wird und damit ja eigentlich nicht mehr statisch ist.

Das einzige was mir einfällt ist ein Define zu erstellen und in file1.h
1
#ifdef TEST
2
void function(void)
3
#endif
und in file1.c
1
#ifdef TEST
2
define staticTest
3
#else
4
define statictest static
5
#endif
6
7
#ifndef TEST
8
static void function(void);
9
#endif
10
...
11
...
12
staticTest void function(void)

Dann wird es aber für mehrere Funktionen sehr unübersichtlich und man 
müsste ja auch den eigentlichen Code dahin anpassen.

Gibt es noch andere möglichkeiten?

von MaWin (Gast)


Lesenswert?

Im Test.c:

#include "getestet.c"

void tests(void) {
// Meine Tests hier
}

von Rolf M. (rmagnus)


Lesenswert?

Verstehe ich nicht ganz. Ein Unittest testet doch ein Modul an seinen 
Schnittstellen. Die statische Funktion gehört da nicht dazu, da sie von 
außen ja gar nicht sichtbar ist.

von MaWin (Gast)


Lesenswert?

Rolf M. schrieb:
> Verstehe ich nicht ganz. Ein Unittest testet doch ein Modul an seinen
> Schnittstellen. Die statische Funktion gehört da nicht dazu, da sie von
> außen ja gar nicht sichtbar ist.

Du gehst davon aus, dass Eine Unit immer eine C-Datei ist.
Das ist nur bei kleinen Projekten so.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

MaWin schrieb:
> Rolf M. schrieb:
>> Verstehe ich nicht ganz. Ein Unittest testet doch ein Modul an seinen
>> Schnittstellen. Die statische Funktion gehört da nicht dazu, da sie von
>> außen ja gar nicht sichtbar ist.
>
> Du gehst davon aus, dass Eine Unit immer eine C-Datei ist.
> Das ist nur bei kleinen Projekten so.

Entweder die statische Funktion ist nur ein "kleiner, unbedeutender" 
Helfer (Implementierungsdetail), dann teste ich ihre Funktion implizit 
dadurch, dass das öffentlich zugängliche Interface die Funktion 
implementiert, die ich sehe möchte, oder sie stellt einen Nutzen zur 
verfügung, der Dokumentiert ist (sonst kann ich sie auch nicht testen), 
dann muss ich sie auch nicht static machen.

von g457 (Gast)


Lesenswert?

> Gibt es noch andere möglichkeiten?

Fast so wie oben, nur wesentlich einfacher:

common.h
1
#ifdef UNITTEST
2
  #define STATIC
3
#else // UNITTEST
4
  #define STATIC static
5
#endif // UNITTEST

file.c
1
#include <common.h>
2
[..]
3
STATIC void foo(void);
4
STATIC T bar(T2);
5
[..]
6
7
STATIC void foo(void)
8
{ [..] }
9
10
STATIC T bar(T2);
11
{ [..] }

Und für aller Testverweigerer: Ja, man will unbedingt auch die nur lokal 
verfügbaren ("statischen") Funtionen testen.

von Rolf M. (rmagnus)


Lesenswert?

MaWin schrieb:
> Rolf M. schrieb:
>> Verstehe ich nicht ganz. Ein Unittest testet doch ein Modul an seinen
>> Schnittstellen. Die statische Funktion gehört da nicht dazu, da sie von
>> außen ja gar nicht sichtbar ist.
>
> Du gehst davon aus, dass Eine Unit immer eine C-Datei ist.

Nö, die kann auch aus 100 C-Dateien bestehen. Dann ist die Funktion 
trotzdem nicht von außen sichtbar.

von g457 (Gast)


Lesenswert?

..minus Strichpunkt wo er nicht hingehört</ingrid>

von MaWin (Gast)


Lesenswert?

Torsten R. schrieb:
> dann muss ich sie auch nicht static machen.

Und was ist, wenn ich sie nur intern im Modul verwende, sie aber 
trotzdem funktional eigenständig ist?

von Rolf M. (rmagnus)


Lesenswert?

g457 schrieb:
> Und für aller Testverweigerer: Ja, man will unbedingt auch die nur lokal
> verfügbaren ("statischen") Funtionen testen.

Dann würde ich allerdings nicht mehr von Unittests sprechen.

von MaWin (Gast)


Lesenswert?

Rolf M. schrieb:
> Nö, die kann auch aus 100 C-Dateien bestehen. Dann ist die Funktion
> trotzdem nicht von außen sichtbar.

Und was ist, wenn eine C-Datei 3 Units beinhaltet?

von MaWin (Gast)


Lesenswert?

Rolf M. schrieb:
> Dann würde ich allerdings nicht mehr von Unittests sprechen.

sondern?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

MaWin schrieb:
> Torsten R. schrieb:

> Und was ist, wenn ich sie nur intern im Modul verwende, sie aber
> trotzdem funktional eigenständig ist?

Na, dann könntest Du Sie doch trotzdem testen. Kommt im Detail dann aber 
auch darauf an, was Du unter "intern im Modul" verstehst. Wenn dass 
Modul aus 20kLOC besteht, dann hat die Funktion sicher nicht mehr 
interne Linkbarkeit und hat ein wohl definierte Funktionalität, die 
Dokumentiert und testbar ist. Wenn es eine kleine Helfer-Funktion ist, 
die einen String in Großbuchstaben konvertiert, dann gehört sie in die 
Tool-Box und wird dort getestet.

Ich hatte noch nie das Bedürfnis, eine statische Funktion zu testen (das 
Gleiche gilt für private member functions). Kann man jemand eine 
konkretes Beispiel geben?

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

MaWin schrieb:
> Und was ist, wenn eine C-Datei 3 Units beinhaltet?

Dann sollte man das ändern.

MaWin schrieb:
> Rolf M. schrieb:
>> Dann würde ich allerdings nicht mehr von Unittests sprechen.
>
> sondern?

Weiß ich nicht. Aber für mich bedeutet Unittest folgendes:
Ich habe ein Modul, das ich als Black Box betrachte. Es bietet nach 
außen definierte Schnittstellen und ein dokumentiertes Verhalten an. Nun 
teste ich an diesen Schnittstellen, ob sich das Modul als ganzes auch 
tatsächlich wie spezifiziert verhält. Da interessieren mich interne 
Funktionen eben nicht. Wie würdest du es definieren?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Rolf M. schrieb:

> Weiß ich nicht. Aber für mich bedeutet Unittest folgendes:
> Ich habe ein Modul, das ich als Black Box betrachte. Es bietet nach
> außen definierte Schnittstellen und ein dokumentiertes Verhalten an. Nun
> teste ich an diesen Schnittstellen, ob sich das Modul als ganzes auch
> tatsächlich wie spezifiziert verhält. Da interessieren mich interne
> Funktionen eben nicht. Wie würdest du es definieren?

Unittests muss man aber nicht als Black-Box-Tests machen. Wenn ich weiß, 
dass es in der Implementierung irgend ein kritischen Pfad gibt, dann 
will ich den ja unbedingt testen (z.B. irgend eine alternative Strategie 
unter bestimmten Bedingungen).

Test von kleinsten Einheiten: Unit-Tests
Test des Zusammenspiels von kleinsten Einheiten: Integration-Tests

von Le X. (lex_91)


Lesenswert?

Rolf M. schrieb:
> Weiß ich nicht. Aber für mich bedeutet Unittest folgendes:
> Ich habe ein Modul, das ich als Black Box betrachte.

Unittests sind white-box-tests.
Neben der Prüfung des output vectors (z.B. Rückgabewert, manipulierte 
globable Symbole etc.) werden im Rahmen von Unittests auch Metriken wie 
Code-/Branch-/Decision-coverage überprüft.
Das klappt nicht bei Blackboxen.

Torsten R. schrieb:
> Ich hatte noch nie das Bedürfnis, eine statische Funktion zu testen (das
> Gleiche gilt für private member functions). Kann man jemand eine
> konkretes Beispiel geben?

Das hat man häufig bei Embedded-SW wo ein Modul eine Funktion hat die 
zyklisch vom RTOS aufgerufen werden muss.
Wenn diese zyklische Funktion mehrere thematisch unabhängige 
Teilaufgaben bearbeitet kann es aus Gründen der Übersichtlichkeit 
durchaus Sinn machen, diese Funktion intern aufzusplitten (z.B. 
CheckInput(), DoSomething(), WriteOutput()).
Man zerlegt also einen Task in mehrere Kleinere.
Kommt durchaus häufig vor.

: Bearbeitet durch User
von Klaus H. (klummel69)


Lesenswert?

Le X. schrieb:
> Unittests sind white-box-tests.

Jupp, ich sag eher:
Unittests können beides: black und auch white-box-tests.

In Bereichen in denen Codecoverage Tests gefordert werden
(FuSi...) müssen auch static Funktionen getestet werden.

Und tatsächlich hatten wir kritischere Fehler bei static Funktionen
als bei von außen zugreifbaren Funktionen.

Ich hatte auch schon einen Kollegen der
alles mögliche auf static gesetzt hat, damit er es nicht testen muss.... 
:-)

von mh (Gast)


Lesenswert?

Rolf M. schrieb:
> MaWin schrieb:
>> Rolf M. schrieb:
>>> Dann würde ich allerdings nicht mehr von Unittests sprechen.
>>
>> sondern?
>
> Weiß ich nicht. Aber für mich bedeutet Unittest folgendes:
> Ich habe ein Modul, das ich als Black Box betrachte. Es bietet nach
> außen definierte Schnittstellen und ein dokumentiertes Verhalten an. Nun
> teste ich an diesen Schnittstellen, ob sich das Modul als ganzes auch
> tatsächlich wie spezifiziert verhält. Da interessieren mich interne
> Funktionen eben nicht. Wie würdest du es definieren?

Da hast du jetzt eine "Unit" mit einer möglichen Definition von Modul 
gleichgesetzt. Wer sagt, dass eine Unit nicht eine Funktion ist? Alles 
was du in dem zitierten Absatz geschrieben hast, kann man auch auf eine 
Funktion als "Unit" anwenden.

von A. S. (Gast)


Lesenswert?

Meines Erachtens scheidet das überschreiben von static aus. Ich würde 
immer Mawins Ansatz (Unit-Tests von innen) bevorzugen, auch wenn der 
Testcode dann im Quelltext steht.

Man könnte alternativ auch definieren, dass der Test in den öffentlichen 
Funktionen aufgehen muss. Dass also static-Funktionen prinzipiell nur 
Code haben, der auch durchlaufen wird, dann braucht es keinen 
gesonderten Test (100%-Testabdeckung durch die anderen Unit-Tests).

Eine dritte Möglichkeit wäre, dass man den Code per Include in eine neue 
C-Datei lokal zieht und um die notwendigen Tests ergänzt.

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.