Testing
-
Definitiv so viel wie möglich Unittesten. In meinen Augen funktioniert testen nur dann gut, wenn man es ohne viel Aufwand immer wieder durchführen kann. Und was könnte einfacher sein, als auf einen Knopf zu drücken, kurz zu warten und dann zu gucken ob die Anzeige rot oder grün ist?
Meiner Erfahrung nach wird am Testen immer als erstes gespart. Deswegen muss Testen so einfach wie möglich sein. Gibts keine automatisierten Tests, traut sich viel selten jemand, größere Refactorings durchzuführen. Das Resultat ist schlechterer Code.
Häufig ist es doch so, dass man Programmteil A schreibt, das man für sich alleine recht einfach manuell testen kann. Dann schreibt man Programmteil B. Der lässt sich auch noch leicht testen. Dann kommt Teil C hinzu. Der benutzt Teile von A und B. Das ist dann schon schwieriger zu testen. Dann ändert jemand was an A. Dann muss man auch C testen, denn es könnte sein, dass A noch funktioniert aber C nicht mehr. Und so gehts immer weiter. Mit automatischen Unittests kann man problemlos einen Teil der Anwendung modifizieren und kann sofort überprüfen, ob der Rest der Anwendung dann auch noch läuft. Zumindest wenn die Unittests von guter Qualität sind.
Und im Idealfall sind die Unittests dann noch durch Continous Integration fest in den Entwicklungsprozess verwoben.
-
volkard schrieb:
DStefan schrieb:
...
Hast Du das auch mal in so weit gebracht, daß die Tests vor der Software waren? Also Test-Driven-Develpment? Falls ja, wie war es?
Ja. Ich habe es sogar selbst initiiert. Also die Einführung von Unit-Tests und die testgesteuerte Arbeitsweise.
Und es war scheußlich, also die Arbeitsweise, nicht die Tests an sich. Zeitverschwendung. Dumm. Frustierend. Was du willst. Ich hab's nicht gemocht und keiner aus dem Team mochte es.
Aber ich hatte mich schon zu weit aus dem Fenster gelehnt, um einfach damit aufzuhören. Wir hatten bereits Richtlinien verfasst und als Team abgesegnet. Also mussten wir weiter machen. Und nach einer gewissen Zeit fanden wir hinein (manche besser als andere). Es begann Spaß zu machen und sich "natürlich" anzufühlen.
Heute favorisiere ich eine Arbeitsweise, die nicht stur nach diesem Rezept vorgeht. Ich schreibe meist nur ein paar (vielleicht 50 Prozent?) der Test vor dem eigentlichen Code, der Rest kommt dann später. Es scheint eine Schmerzschwelle zu geben. Wenn die Tests nicht innerhalb von zwei oder drei Arbeitstagen laufen (manche Funktionen arbeiten ja erst korrekt, wenn man eine Menge anderer Funktionen laufen hat), wird es wieder frustrierend. Wenn ich kann, trage ich dem Rechnung, indem ich bestimmte Funktionen zwar implementiere (etwa um Schnittstellen darzulegen) aber zunächst nicht teste.
Wichtig scheint mir zu sein, dass es am Ende, also spätestens wenn man den Code frei gibt, Unit-Tests gibt, die alle relevanten Teile des Codes abdecken.
Stefan.
-
DStefan schrieb:
Wenn die Tests nicht innerhalb von zwei oder drei Arbeitstagen laufen (manche Funktionen arbeiten ja erst korrekt, wenn man eine Menge anderer Funktionen laufen hat), wird es wieder frustrierend. Wenn ich kann, trage ich dem Rechnung, indem ich bestimmte Funktionen zwar implementiere (etwa um Schnittstellen darzulegen) aber zunächst nicht teste.
Wichtig scheint mir zu sein, dass es am Ende, also spätestens wenn man den Code frei gibt, Unit-Tests gibt, die alle relevanten Teile des Codes abdecken.
Wenn ein Test erst die Fertigstellung von anderen Programmteilen erfordert oder man für einen Test mehrere Tage braucht, dann handelt es sich aber nicht mehr um Unittests und man sollte das eigene Testkonzept nochmal überdenken. Ein Unittest ist zum Testen einer (kleinsten) Einheit, also z.B. einer einzelnen Methode oder Funktion. Wenn man dafür erst andere Programmteile benötigt, dann sollte man diesen Mocken.
Was Du da beschreibst, klingt eher nach Integrationstests. Und auch die sollten nicht mehrere Tage Arbeit kosten.
-
byto schrieb:
DStefan schrieb:
Wenn die Tests nicht innerhalb von zwei oder drei Arbeitstagen laufen (manche Funktionen arbeiten ja erst korrekt, wenn man eine Menge anderer Funktionen laufen hat), wird es wieder frustrierend. Wenn ich kann, trage ich dem Rechnung, indem ich bestimmte Funktionen zwar implementiere (etwa um Schnittstellen darzulegen) aber zunächst nicht teste.
Wichtig scheint mir zu sein, dass es am Ende, also spätestens wenn man den Code frei gibt, Unit-Tests gibt, die alle relevanten Teile des Codes abdecken.
Wenn ein Test erst die Fertigstellung von anderen Programmteilen erfordert oder man für einen Test mehrere Tage braucht, dann handelt es sich aber nicht mehr um Unittests und man sollte das eigene Testkonzept nochmal überdenken. Ein Unittest ist zum Testen einer (kleinsten) Einheit, also z.B. einer einzelnen Methode oder Funktion. Wenn man dafür erst andere Programmteile benötigt, dann sollte man diesen Mocken.
Was Du da beschreibst, klingt eher nach Integrationstests. Und auch die sollten nicht mehrere Tage Arbeit kosten.
Ich rede nicht von der Erstellung der Tests, sondern von der Erstellung des Codes, der getestet wird. Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht. Das ist doch nichts Besonderes!
Sorry, aber Unit-Tests sind zum Testen aller und nicht bloß der kleinsten Einheiten da. Wenn eine Einheit über andere Einheiten implementiert ist, dann ist der Code, der diese "umschließende" Einheit testet, ein Unit-Test. Warum auch nicht? Es kommt doch nicht auf die Größe an, damit etwas ein Unit-Test ist!
Stefan.
-
DStefan schrieb:
Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht.
Darf ich fragen, was so eine Methode dann macht (mir ist bis jetzt nocht nichts so aufwändiges unter die Finger gekommen)?
-
Badestrand schrieb:
DStefan schrieb:
Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht.
Darf ich fragen, was so eine Methode dann macht (mir ist bis jetzt nocht nichts so aufwändiges unter die Finger gekommen)?
void* CoolAllocator::alloc(size_t) wäre so ein fall.
binary_search natürlich.
md5, gzip
is_prime_number, rand, je nach qualitätsanspruch
also vorkommen kann's.
-
Herrmann schrieb:
wie läuft bei euch auf Arbeit das Testen von Programmen und Programmteilen ab?
Meistens so, dass es dem Programmierer überlassen ist, wie er es macht. Einmal durfte ich an einem Projekt teilnehmen, wo Testcode Pflicht war und es gab eine Vorgabe, wieviel Prozent vom Code beim Testen abgedeckt sein sollten (80% oder so, glaube ich).
In letzter Zeit schreibe ich relativ viel Testcode, aber nicht, weil ich aufs Testen scharf bin, sondern, weil ich u.a. wissen will, wieviele CPU Takte meine Funktionen benötigen und ob der Code mit allen Compiler Optimierungsstufen funktioniert...
-
Badestrand schrieb:
DStefan schrieb:
Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht.
Darf ich fragen, was so eine Methode dann macht (mir ist bis jetzt nocht nichts so aufwändiges unter die Finger gekommen)?
Mitarbeiter::calcResturlaub()
Unter Berücksichtigung von:
- Wechselnden Arbeitsverträgen mit unterschiedlichen Urlaubsansprüchen im Betrachungszeitraum.
- Übernahme von Urlaub aus Vorjahren, aber nur, falls ein Antrag vorliegt und genehmigt wurde.
- Automatischem Inkrement des Anspruchs nach Betriebszugehörigkeit, wobei die Betriebszugehörigkeit, der maximale Anspruch und die Höhe des Inkrements von einem Dutzend (oder so) Bedingungen abhängen.
- Bereits genommenem Urlaub
- Krankheitstagen innerhalb des bereits genommenem Urlaubs.
- usw.
Dieses Beispiel fällt mir spontan ein. Wobei hier nicht bloß die Implementierung des produktiven Codes, sondern auch der Tests verdammt viele Tage in Anspruch genommen haben.
Dies ist übrigens auch ein Beispiel für eine Funktion, die ich um ungefähr 500% unterschätzt hatte
Stefan.
-
DStefan schrieb:
Mitarbeiter::calcResturlaub()
Unter Berücksichtigung von:
- Wechselnden Arbeitsverträgen mit unterschiedlichen Urlaubsansprüchen im Betrachungszeitraum.
- Übernahme von Urlaub aus Vorjahren, aber nur, falls ein Antrag vorliegt und genehmigt wurde.
- Automatischem Inkrement des Anspruchs nach Betriebszugehörigkeit, wobei die Betriebszugehörigkeit, der maximale Anspruch und die Höhe des Inkrements von einem Dutzend (oder so) Bedingungen abhängen.
- Bereits genommenem Urlaub
- Krankheitstagen innerhalb des bereits genommenem Urlaubs.
- usw.
Dieses Beispiel fällt mir spontan ein. Wobei hier nicht bloß die Implementierung des produktiven Codes, sondern auch der Tests verdammt viele Tage in Anspruch genommen haben.
Dies ist übrigens auch ein Beispiel für eine Funktion, die ich um ungefähr 500% unterschätzt hatte
Sie ruft also so um die 10 Hilfsfunktionen auf, die die Daten zusammentragen und Zwischenergebnisse berechnen?
-
volkard schrieb:
DStefan schrieb:
Mitarbeiter::calcResturlaub()
Unter Berücksichtigung von:
- Wechselnden Arbeitsverträgen mit unterschiedlichen Urlaubsansprüchen im Betrachungszeitraum.
- Übernahme von Urlaub aus Vorjahren, aber nur, falls ein Antrag vorliegt und genehmigt wurde.
- Automatischem Inkrement des Anspruchs nach Betriebszugehörigkeit, wobei die Betriebszugehörigkeit, der maximale Anspruch und die Höhe des Inkrements von einem Dutzend (oder so) Bedingungen abhängen.
- Bereits genommenem Urlaub
- Krankheitstagen innerhalb des bereits genommenem Urlaubs.
- usw.
Dieses Beispiel fällt mir spontan ein. Wobei hier nicht bloß die Implementierung des produktiven Codes, sondern auch der Tests verdammt viele Tage in Anspruch genommen haben.
Dies ist übrigens auch ein Beispiel für eine Funktion, die ich um ungefähr 500% unterschätzt hatte
Sie ruft also so um die 10 Hilfsfunktionen auf, die die Daten zusammentragen und Zwischenergebnisse berechnen?
Ungefähr, ja. Willst du darauf hinaus, dass man die Hilfsfunktionen getrennt hätte testen können? Die meisten waren private, so dass das nicht ging.
Stefan.
-
Die meisten waren private, so dass das nicht ging.
#define private public
-
DStefan schrieb:
volkard schrieb:
Sie ruft also so um die 10 Hilfsfunktionen auf, die die Daten zusammentragen und Zwischenergebnisse berechnen?
Ungefähr, ja. Willst du darauf hinaus, dass ...
Gar nicht. Ich wollte den vagen Eindruck geklärt haben, ob Du da einen 500-Zeiler gebaut hast.
Man hätte durch
Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht.
den Eindruck gewinnen können.
-
DStefan schrieb:
Sorry, aber Unit-Tests sind zum Testen aller und nicht bloß der kleinsten Einheiten da. Wenn eine Einheit über andere Einheiten implementiert ist, dann ist der Code, der diese "umschließende" Einheit testet, ein Unit-Test. Warum auch nicht? Es kommt doch nicht auf die Größe an, damit etwas ein Unit-Test ist!
Angenommen Du hast Einheit A, B und C. Einheit C benutzt Einheit B und Einheit B benutzt Einheit A. Du schreibst einen Unittest um Einheit C zu testen. Damit testest Du implizit auch A und B. Nun gibts irgendwann Änderungen und der Test zu C schlägt fehl. Du weisst nun zwar, dass irgendwo ein Fehler ist, siehst aber nicht umbedingt auf den ersten Blick, ob der Fehler in A, B oder C liegt.
Deswegen ist der Sinn von Unittests eben doch, die kleinsten Einheiten eines Programms zu testen. Das interessante daran ist, dass solche Unittests nicht nur helfen, Fehler schneller zu finden und zu beheben. Sie helfen sogar dabei, das Programm besser zu strukturieren! Es hilft dabei Seiteneffekte zwischen Programmteilen zu verhindern, weil sich diese eben isoliert nur schwer testen lassen.
The goal of unit testing is to isolate each part of the program and show that the individual parts are correct.
-
volkard schrieb:
DStefan schrieb:
volkard schrieb:
Sie ruft also so um die 10 Hilfsfunktionen auf, die die Daten zusammentragen und Zwischenergebnisse berechnen?
Ungefähr, ja. Willst du darauf hinaus, dass ...
Gar nicht. Ich wollte den vagen Eindruck geklärt haben, ob Du da einen 500-Zeiler gebaut hast.
Man hätte durch
Und hier kann es vorkommen, dass man zur Implentierung einer einzigen Methode einer Klasse Tage braucht.
den Eindruck gewinnen können.
Oh nein! 500-Zeiler kommen mir nicht ins Haus. Jedenfalls nicht in produktivem Code. Wenn man z.B. eine neue Lib ausprobiert schreibt man schonmal eher, wie einem der Schnabel gewachsen ist. Ob du's glaubst oder nicht, ich bin ein Code-Ästhet
Stefan.
-
byto schrieb:
DStefan schrieb:
Sorry, aber Unit-Tests sind zum Testen aller und nicht bloß der kleinsten Einheiten da. Wenn eine Einheit über andere Einheiten implementiert ist, dann ist der Code, der diese "umschließende" Einheit testet, ein Unit-Test. Warum auch nicht? Es kommt doch nicht auf die Größe an, damit etwas ein Unit-Test ist!
Angenommen Du hast Einheit A, B und C. Einheit C benutzt Einheit B und Einheit B benutzt Einheit A. Du schreibst einen Unittest um Einheit C zu testen. Damit testest Du implizit auch A und B. Nun gibts irgendwann Änderungen und der Test zu C schlägt fehl. Du weisst nun zwar, dass irgendwo ein Fehler ist, siehst aber nicht umbedingt auf den ersten Blick, ob der Fehler in A, B oder C liegt.
Deswegen ist der Sinn von Unittests eben doch, die kleinsten Einheiten eines Programms zu testen. Das interessante daran ist, dass solche Unittests nicht nur helfen, Fehler schneller zu finden und zu beheben. Sie helfen sogar dabei, das Programm besser zu strukturieren! Es hilft dabei Seiteneffekte zwischen Programmteilen zu verhindern, weil sich diese eben isoliert nur schwer testen lassen.
Du hast Recht, wenn du sagst, dass Unit-Tests helfen, Programme besser zu strukturieren. Oder zumindest helfen können, denn natürlich kann man auch mit Unit-Tests den größten Mist verzapfen.
Den ersten Teil deines Beitrags aber finde ich nicht plausibel. Natürlich müssen A und B getestet werden. Wenn aber C die beiden anderen Teile verwendet, muss es auch für C einen Unit-Test geben.
Denn erstens kann C ja die Teile falsch verwenden, und es ist denkbar, dass A und B für sich genommen zwar fehlerfrei sind, im Zusammenspiel aber nicht funktionieren. Ein "Kooperationsfehler" käme also nur im Test von C an's Licht.
Zweitens enthält C immer auch Code, und sei es nur (was nach meiner Erfahrung eher selten vorkommt) solchen Code, der die verwendeten Teile aktiviert (Variablen anlegen, Methoden von A und B aufrufen). Deshalb muss es auch dann für C einen Unit-Test geben, wenn C ausschließlich A und B verwendet.
Ich spreche mich hier ausdrücklich nicht für implizite Tests aus! Die braucht man nicht und die soll man auch nicht schreiben. Aber ich sehe keinen Grund dafür, nur kleinste Einheiten per Unit-Tests zu testen.
Übrigens: Was ist eigentlich eine "kleinste Einheit"? Nur eine, die selbst keine anderen Einheiten verwendet?
Stefan.
-
_P schrieb:
Die meisten waren private, so dass das nicht ging.
#define private public
Also wenn schon, dann so:
class MyClass { // ... #ifdef WE_ARE_TESTING public: #else private: #endif // ... };
Mit deinem Vorschlag könnte man alles einfach public machen, oder?
Letztlich halte ich eine wie auch immer geartete "Veröffentlichung" privater Teile für keine gute Lösung. Aus verschiedenen Gründen.
Stefan.
-
DStefan schrieb:
Ich spreche mich hier ausdrücklich nicht für implizite Tests aus! Die braucht man nicht und die soll man auch nicht schreiben.
Aber was sind implizite Tests?
-
volkard schrieb:
DStefan schrieb:
Ich spreche mich hier ausdrücklich nicht für implizite Tests aus! Die braucht man nicht und die soll man auch nicht schreiben.
Aber was sind implizite Tests?
Im Sinn von bytos Beschreibung: Man testet C, das B verwendet, das A verwendet, und glaubt, dass man mit dem Test von C auch A und B getestet hat. Implizit halt.
Stefan.
-
DStefan schrieb:
Den ersten Teil deines Beitrags aber finde ich nicht plausibel. Natürlich müssen A und B getestet werden. Wenn aber C die beiden anderen Teile verwendet, muss es auch für C einen Unit-Test geben.
Schon richtig. Aber wenn Du für obigen Teil Unittests für A, B und C schreibst, dann wird A implizit zweimal mitgetestet (von B und C) und B einmal (durch C). Besser wäre es, solche Seiteneffekte im Vorhinein zu verhindern. Sind A, B und C frei von Seiteneffekten, können sie unabhängig voneinander getestet werden. Die Integration von A, B und C kann dann über Integrationstests (siehe Unterschied zu Unittests!!) getestet werden.
Häufig kann man Seiteneffekte nicht gänzlich verhindern. Aber auch dafür gibts ne Möglichkeit, nämlich Mock-Objekte. Durch Mock-Objekte kann man das mehrfache implizite Testen immer gleicher Programmteile verhindern. Das ist vor allem in größeren Projekten mehr als sinnvoll, weil man dadurch die Ausführungsgeschwindigkeit der Tests minimieren kann.
Denn erstens kann C ja die Teile falsch verwenden, und es ist denkbar, dass A und B für sich genommen zwar fehlerfrei sind, im Zusammenspiel aber nicht funktionieren. Ein "Kooperationsfehler" käme also nur im Test von C an's Licht.
Zweitens enthält C immer auch Code, und sei es nur (was nach meiner Erfahrung eher selten vorkommt) solchen Code, der die verwendeten Teile aktiviert (Variablen anlegen, Methoden von A und B aufrufen). Deshalb muss es auch dann für C einen Unit-Test geben, wenn C ausschließlich A und B verwendet.
Wie gesagt: es gibt einen Unterschied zwischen Unittests, die per Definition nur eine kleine Einheit testen (idR eine Methode/ Funktion) und Integrationstests, die das Zusammenspiel der einzelnen Module einer Anwendung testen. Integrationstests sind meistens aufwändiger und haben eine längere Ausführungsgeschwindigkeit, vor allem wenn periphäre Systeme wie Datenbanken mit ins Spiel kommen.
Übrigens: Was ist eigentlich eine "kleinste Einheit"? Nur eine, die selbst keine anderen Einheiten verwendet?
idR ist damit eine einfache Methode oder Funktion gemeint.
Was Du alles schreibst, ist ja nicht falsch. Aber Du fasst das alles unter Unittests zusammen und das ist so nicht ganz korrekt.
-
byto schrieb:
Aber wenn Du für obigen Teil Unittests für A, B und C schreibst, dann wird A implizit zweimal mitgetestet (von B und C) und B einmal (durch C). Besser wäre es, solche Seiteneffekte im Vorhinein zu verhindern. Sind A, B und C frei von Seiteneffekten, können sie unabhängig voneinander getestet werden. Die Integration von A, B und C kann dann über Integrationstests (siehe Unterschied zu Unittests!!) getestet werden.
Häufig kann man Seiteneffekte nicht gänzlich verhindern. Aber auch dafür gibts ne Möglichkeit, nämlich Mock-Objekte. Durch Mock-Objekte kann man das mehrfache implizite Testen immer gleicher Programmteile verhindern. Das ist vor allem in größeren Projekten mehr als sinnvoll, weil man dadurch die Ausführungsgeschwindigkeit der Tests minimieren kann.
Entschuldige byto, aber das klingt doch ziemlich verrückt!
Nach deiner ursprünglichen Definition ist Einheit C implementiert über die Einheit B und diese wiederum über Einheit A. Du schreibst weiter, dass ein Test von Einheit C "implizit" die Einheiten A und B testet - und das hältst du für falsch. Nach deiner Definition dürfte man somit ausschließlich einen Unit-Test für Einheit A schreiben, denn dies ist eine "kleinste Einheit". Einheit B testet schließlich auch "implizit" - nämlich Einheit A.
Du siehst selbst, wohin das führt und forderst deshalb, solche "Seiteneffekte" zu vermeiden. Wo das nicht geht, möchtest du "Mock Objekte" einsetzen.
Zunächst einmal ist der Begriff "Seiteneffekt" in diesem Zusammenhang nicht sehr glücklich gewählt. Üblicherweise bezeichnet man als Seiteneffekt etwas ganz andres. Bleiben wir lieber bei "impliziter Test".
Dann deine Schussfolgerung oder Behauptung, durch den Test von C würden A und B implizit mit getestet. Das stimmt meines Erachtens doch gar nicht. Oder wenigstens nicht zwangsläufig. Der Code von A und B wird ausgeführt, das ist richtig. Aber wenn man's richtig macht, wird dieser Code im Test von C nicht getestet! Er muss halt nur ausgeführt werden, damit C funktioniert.
Auch was die Mock-Objekte angeht, stimme ich nicht mit dir überein. Mock-Objekte verwendet man, um in Unit-Tests langwierige oder während der Tests nicht verfügbare Operationen zu simulieren. Man kann sie auch verwenden, um Tests reproduzierbar zu machen. In allen Fällen aber bieten Mock-Objekte einen simulierten Ausschnitt der Umgebung der zu testenden Software. Das können Datenbank-Zugriffe sein (weil z.B. der Status der Daten nicht unter der Kontrolle des Testers liegt) oder Zugriffe auf externe Software (etwa Web-Services, die bestimmte Daten liefern). Ich habe auch schon Mock-Objekte geschrieben, die einen VoIP-Dialer simulieren - schließlich will man ja nicht, dass bei jedem Unit-Test irgendwelche Leute angerufen werden
Du schlägst vor, man solle Mock-Objekte auch verwenden, um "Seiteneffekte" beim Testen, also "implizites" Testen zu vermeiden. Aber dazu müsste man doch beim Test von C die Einheiten B und A entfernen, so dass MockB und MockA zum Einsatz kommen! C muss also auf den Unit-Test eigens vorbereitet werden! Und das alles nur, um zu verhindern, dass beim Test von C Code in A und B ausgeführt wird, der ja bereits getestet ist. Ich sage dir, um sowas zu tun bräuchte ich schon einen verdammt guten Grund. Und die von dir vorgestellte "reine Lehre" des Unit-Testings ist aus meiner Sicht überhaupt kein Grund.
Nun gut. Angenommen, wir hätten jetzt C dazu gebracht, im Unit-Test statt B und A MockB und MockA zu verwenden. Wir schreiben unseren Test und er läuft. Aber was haben wir jetzt getestet? (Das ist ein Problem, das immer auftritt, wenn man Mock-Objekte verwendet.) Wir haben getestet, dass C zum Beispiel MockB korrekt verwendet. Aber dies geschieht im Sinne von MockB und nicht im Sinne von B selbst. Alle relevanten Änderungen in B müssen peinlichst in MockB nachvollzogen werden, sonst ist unser Unit-Test von C nicht mehr korrekt. Wir nehmen unter Umständen eine Heidenarbeit auf uns, testen C nicht in seiner "natürlichen", sondern nur in einer idealisierten Umgebung, und das alles nur, um nicht mit C implizit auch A und B zu testen?
Mir geht das zu weit. Ich möchte, im Gegenteil, alle Unit-Tests möglichst so schreiben, dass sie den Code testen, der später auch prouktiv wird. Natürlich geht das nicht immer, wie ich oben schon sagte, aber ich finde, man sollte eine Menge dafür tun.
Stefan.