Unit Tests
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Für jede Unit (jeden Programm-Baustein) wird ein eigener Test entwickelt, der sich als RegressionsTest automatisch ausführen lässt.
Wesentlich ist die Einbettung der einzelnen Tests - in einem Projekt können es tausende Tests sein - in eine automatische TestUmgebung (TestingFramework), die den Aufwand minimiert. Im Idealfall erkennt die Testumgebung durch Reflektion (IntroSpektion) automatisch alle Methoden am Namen (z. B. mit "Test" beginnend) und führt sie automatisch aus.
Verweise | |
Siehe auch :
Für .NET und insbesondere für C#, VB.NET, J# und Managed C++ gibt es unter http://www.csunit.org/ ein sehr gutes und sehr einfach einzusetzendes TestingFramework. Und dann gibt es da auch noch unter http://www.nunit.org ein entsprechendes TestingFramework.
Literatur:
Testabdeckung | |
Zwecks Testabdeckung sind Unittests alleine nicht ausreichend (siehe DreiTestAxiome). Beispielsweise könnten sie durch AkzeptanzTests komplettiert werden.
- Das folgt nicht aus den drei Axiomen. Die Summe aus den Tests für Module ohne Submodule und den Tests für Module, die Submodule enthalten kann durchaus zu einer vollständigen Testabdeckung führen. Die Axiome sagen lediglich, dass man sich darauf nicht verlassen kann. -- SDö
- Versteh ich nicht: was bringt mir denn ein Test, wenn ich mich auf ihn nicht verlassen kann? --bs
- Auf den Test kannst du dich verlassen. Schwierig wird's mit Pauschalaussagen über die Testabdeckung. Für eine in Module gesplittete Anwendung testen Unit-Tests eines Moduls implizit auch einen Teil der öffentlichen Schnittstelle der verwendeten (Sub-) Module. Die Axiome sagen, was man daraus nicht folgern kann. Und dennoch: Schreibt man für alle Module Unit-Tests, kann das m. E. schon als Modulgruppen-Test (Test einer Anwendung oder Laufzeit-Komponente) durchgehen. Mit den Akzeptanz-Tests hast du dagegen völlig recht und auch den System-Test eines Gesamtsystems aus mehreren Anwendungen/Laufzeitkomponenten sehe ich nicht als Unit-Test; selbst wenn er automatisiert und wiederholbar ist. Als allgemeinen Begriff für automatisierte Tests verwende ich eher RegressionsTest. Bei Unit-Tests ist immer etwas unklar, was denn nun eigentlich mit "Unit" gemeint ist. Meist meint man das, was das Test-Tool als Unit verwaltet. -- SDö
Ist es wirklich wichtig zu wissen, was Axiome besagen? Oder sollte uns nicht vielmehr wichtiger sein, was der Kunde meint? Auf der Testseite weiss ich jedenfalls, dass mir automatische Tests (egal wie sie heissen, Unit-, Entwickler-, Akzeptanztest, etc.) in Verbindung mit Testabdeckung eine Menge ueber die Qualitaet sagen. Fuer manche unsere Lieferanten haben wir die Regel eingefuehrt, dass wir Code nur noch akzeptieren, wenn die mitgelieferten automatischen Tests eine Quelltextabdeckung von ueber 95% erreichen. Das ist zwar immer noch keine Garantie, aber es bedeutet fuer unsere Entwicklungspartner, dass sie eigentlich nur einen oekonomisch sinnvollen Weg haben, diese Zielvorgabe zu erreichen: Testgetriebene Entwicklung mit gnadenloser Refaktorierung und kontinuierlicher Integration. Und selbstverstaendlich schulen wir die Mitarbeiter unserer Entwicklungspartner, um die Einfuehrung zu beschleunigen. (Toyota verfolgt einen aehnlichen Ansatz mit seinen Lieferanten.) Damit unsere Partner auch wissen, was von ihnen erwartet wird, liefern wir die Akzeptanztest (inclusive Performancetests) gleich mit. ManfredLange
Fragen | |
Hat einer von euch schon mal mit JUnit für J2ME? ( http://xprogramming.com/ftp/TestingFramework/j2me/J2MEUnit1_0.zip) zu tun gehabt ? - mj
Diskussion | |
Ich bin öfters im Zwiespalt, wie ich meine Tests schneiden soll:
- Eigentlich möchte ich nur meine Paketschnittstellen testen und die Internas im Dunkeln lassen. Damit bleiben meine Tests stabil und sind auch noch einige Refactorings später aussagekräftig.
- Aber manchmal gibt's eben doch knackige Internas, für die der nächste Schnittstellen-Test einen zu grossen Schritt bedeuten. In diesem Fall möchte ich schon auch mal Whitebox testen. Falls jetzt das Design über den Hauffen geschmissen wird, muss man solche Test gleich mit entsorgen ...
Wie geht Ihr mit dieser Thematik um ? -- mj
- Die UnitTests dienen auch als Spezifikation für die erwünschte Funktionalität. Jedes Modul hat einen definierten Zweck, der getestet werden kann. Auch interne Module. Also können auch die internen Module getestet werden. Wenn sich der Zweck der internen Module ändern soll, muss man deren Tests ändern. Wenn die internen Module entfallen, kann man auch deren Tests entsorgen. Wichtig ist nur, wie man die Test organisiert.
- Mit internen Modulen habe ich kein Problem. Aber wenn für dieses internene Modul noch interne Tests nötig sind fängt mein Zwiespalt an. Konkretes Beispiel: Ich mache gerade ein Dokument-Modell für einen Text Editor. Zur Verwaltung von Dokumentelementen hab ich eine nicht triviale Baumstruktur, die ich eigentlich nicht veröffentlichen möchte.
- Wie soll ich jetzt mit dem Baumtest verfahren ? Bis das Modell fertig ist werden sich sicher noch einige Dinge in der Modulstruktur ändern ... ich hab mir überlegt, dass ich zumindest eine Namenskonvention verwende um flüchtige und nicht so flüchtige Test auseinanderhalten zu können. --mj
- Ein interessantes TestMuster? wird von NetBeans verwendet. Die Tests, die interne Funktionalität (in diesem Falle private, protected oder default) testen, werden als nested Classes implementiert. Sie sehen also die nicht veröffentlichte Funktionalität und, da selbst öffentlich, können von JUnit aufgerufen werden. Das Clevere dabei ist, dass Java jede, auch eine nested, Klasse in eine eigene Datei kompiliert. So wird die Klasse A.B in die Datei A$B.class compiliert. Bei der Auslieferung kann man dann die kompilierten Testklassen einfach aus dem generierten JAR auschließen, oder solche Klassen in einem separaten JAR ausliefern.
- Jup das kenn ich auch ... ich verwende solche Test aber nicht so gerne. Ich habe meine Testklassen gerne schon in den Sourcen getrennt vom Rest. -- mj
- In C++ kann man eine ähnliche Vorgehensweise verwenden. Man kann die Testklasse friend der getesteten Klasse machen, oder man kann zu etwas schmutzigeren Tricks greifen (#define private public).
- Die Idee dahinter ist, statt die getestete Funktionalität zu weit zu veröffentlichen, die Tests an die Stelle zu bringen, wo sie bereits sichtbar ist, und nur die Tests zu veröffentlichen. --gR
- Hmmm ... ist zumindest ein anderer Ansatz. Ich werde mal darüber nachdenken :-).
- Meiner Meinung nach sollten die Tests bzw. die Testsuiten die spezifizierte Struktur der Funktionalität kopieren. (Damit meine ich nicht nur die physische Struktur der Module. Es kann z.B. auch Tests geben, die sich einem Aspekt von mehreren Modulen widmen) -- gR
- Sehe ich gleich.
Wenn ich TestgetriebeneEntwicklung betreibe, sind Tests für mich viel mehr Design-Hilfe als nur "einfach Tests". Durch das Testen der "Interna" (insbesondere, wenn es sich um komplexe handelt), schaffe ich es meist viel besser, selbige in kleine, entkoppelte Einheiten zu zerlegen. Nach meiner Erfahrung würde ich daher mutmaßen, dass gerade durch das Schreiben von WhiteBoxTests, Änderungen an den Interna einfacher werden! Wenn ich dann doch ab und zu einen Test wegwerfen muss, stört mich das meist nur noch wenig.
- Hi Ilja :-)), eindeutig ja, wenn ich keine internen Tests schreiben kann, hab ich viel mehr Mühe, komplexe Internas zu entwickeln .-)
Ich würde daher vorschlagen, einfach für eine Weile Deine Ängste zu ignorieren, Mut zu fassen (ist nicht umsonst einer der Grundwerte von ExtremeProgramming) und es für eine Weile mit WhiteBoxTests auszuprobieren... ;) -- IljaPreuß
- Das hat nicht's mit Angst zu tun, wie gesagt ich benutze interne UnitTests genau wie du. Aber es schwingt etwas Unbehagen mit. Wenn ich mir mein Problem so überlege, läuft es bei mir folgendermassen:
- * Externe / interne Tests schreiben.
- * Entwickeln (und irgendwann dann mal interne Struktur ändern)
- * Dann bin ich zu faul / oberflächlich um meine gesamte Teststruktur auf Konsistenz zu pruefen (ja die Test werden mit-refactored, aber manchmal ist einfach die Semantik geändert)
- * Ich hab jetzt also Test die alle wieder grün sind und eine geänderte Struktur ... und ein schlechtes Gefühl wegen inkonsistenter Tests. So degeneriert im schlimmsten Fall ein großer Teil der Testbasis im Laufe der Zeit.
- * Ich hab gestern darüber mit einem Bekannten diskutiert, er hat vorgeschlagen für interne- und schnittstellen-Tests getrennte Sourcebäume zu benutzen. Damit kann ich dann Internes geziehlt wegschmeissen und vermeide von vornherein durchmischte Tests. Das ist meine derzeitige Lösung :-) -- mj
- Ich finde, man kann Software nicht einfach in "interne" und "externe" trennen. Die Kapselung ist meistens vielschichtiger. Wenn ich eine Klasse schreibe, gehören deren public, protected usw. Methoden zu deren externen Schnittstelle. Die Klasse selbst kann aber ein internes Implementierungsdetail eines größeren Moduls sein (einer anderen Klasse oder einer Bibliothek). Die Tests dieser Klasse, die nur deren externe Schnittstelle verwenden, sind, was die Klasse betrifft Blackbox-Tests. Die Testsuite, die das größere Modul testet, muss aber die interne Struktur des Moduls kennen, um die Tests überhaupt zu enthalten. Das größere Modul wird also "whiteboxgetestet".
- Es ist also nur die Frage, in welcher Box sind die Tests drin. Die Innenseite des Box ist weißgestrichen, die Außenseite schwarz :-)
- Kommt jetzt Schrödingers Katze :-) ?
- Du hast schon recht, die whitebox Tests sind meine internen Tests. Zuerst kümmere ich mich um die Schnittstellen, dann um deren Impl.. Das führt dazu, dass die Impl. manchmal sehr kurzlebig ist, daher sind dann auch deren whitebox Tests obsolet.
- Wenn ich jetzt meine Test von vornherein getrennt habe, kann ich relativ problemlos meine whitebox Tests wegschmeissen und hab immer noch die gültigen blackbox Tests. Wenn ich nicht von Beginn an auf eine solche Trennung achte, wird's an dieser Stelle dann entsprechend komplizierter... -- mj
- Ich finde es etwas problematisch. Für mich sind die UnitTests immer eine Art ausführbare Spezifikation die implementiert wird. Nur wenn sich die Spezifikation / Test ändert, ist es sinnvoll die Tests zu ändern oder sie wegzuschmeißen. Auch die "internen" Tests sind eine Spezifikation an die internen Module, von denen andere Module abhängig sind. Die Tests sollten also so lange bestehen, so lange es Module gibt, die von dem spezifizierten Verhalten abhängig sind, bestehen.
- Nochmal, interne Tests sind für Modulinternas. Modulintern heisst, es gibt keine externen Referenzen / Abhängigkeiten darauf. Alles was extern verwendet wird, wird ganz normal extern getestet. Interne Test benötige ich, um die Entwicklungsschritte klein und übersichtlich zu halten ... klar ist das auch eine Art Spec. Allerdings keine Spec die eine interne Neustrukturierung des Moduls überleben muss.
- Genau das meine ich ja. Sie sind für das Modul intern, und testen die internen Teile des Moduls. Wenn du das Modul anders strukturierst, so dass die interne Teile nicht mehr oder anders gebraucht werden (deren Spezifikation ändert sich), dann musst Du auch die Tests ändern bzw. wegschmeißen.
KategorieTesten KategorieXp
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 3. April 2007 7:53 (diff))