Laden...

Festellen, ob sich eine Methode geändert hat

Erstellt von Quaneu vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.052 Views
Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 10 Jahren
Festellen, ob sich eine Methode geändert hat

Hallo,

ich schreibe gerade Tests und dabei hat sich mir eine Frage gestellt...

Ich habe eine Methode per UnitTest zu 100% abgedeckt.
Nun erweitere ich die Methode z.B. es gab damals ein if ... else ... und nun if ... else if ... else ... und ich vergesse den Test anzupassen. Dieser wird trotzdem erfolgreich durchlaufen. Dies stört mich jedoch und daher suche ich eine Möglichkeit, festzustellen, ob sich eine Methode geändert hat, damit ich einen Test schreiben kann, der mich daran erinnert den Test anzupassen. Doch leider finde ich keine Lösung.

Am liebsten wäre es mir, von einer Methode einen Hash zu speichern und zur Laufzeit diesen zu vergleichen, doch ich finde keine Möglichkeit.

Hätte jemand eine Idee?

Schöne Grüße
Quaneu

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo Quaneu,

Wenns nur um die Erinnerung an die Test-Anpassung geht, warum keine einfachere Möglichkeit?*Versionskontrollsystem: dort siehst du welche Methode sich geändert hat. Erfordert dann halt Disziplin 😉 *Compiler-Warnung/Fehler per #warning-Direktive ausgeben, die erinnert dass ein Test fehlt bzw. nicht alles abdeckt. Muss händisch erstellt werden, kann auch als Fehler ausgegeben werden. *Test-Abdeckung erneut ermitteln und wenn dieser < 100% ist, dann nachbessern. Vermutlich gibt es in VS sogar eine Regel, die das automatisch macht und eine Warnung/Fehler ausgibt, wenn das Ziel der Abdeckung nicht erreicht wird. Ich weiß aber nicht ob es das tatsächlich gibt, aber sonst kann das auch selbst erweitert werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 10 Jahren

Danke für Deine schnelle Antwort.
*Das mit der Disziplin ist so eine Sache 😃. Darauf will ich mich nicht 100% verlassen. *Compiler-Warnung/Fehler müsste ich ja auch selbst schreiben. Mir geht es darum, dass ich im schlimmsten Fall erinnert werde und d.h. ich habe es vergessen, darum würde ich ja auch vergessen eine #warning zu schreiben. *Das mit der Testabdeckung müsste ich mir mal anschauen.

Meine erste Idee war es. In einem fertigen Test z.B. den Hash einer Methode zu speichern und diesen bei jedem Durchlauf zu prüfen. So würde ich sofort merken, wenn ich eine Methode geändert habe, aber den Test nicht angepasst.

G
497 Beiträge seit 2006
vor 10 Jahren

wenn man Methoden vollständig von Unit-Tests abdecken will, ändert man doch als erstes den Test und sorgt dann dafür, dass die Methode den Test wieder erfolgreich absolviert (TDD).

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 10 Jahren

Ich weiß so sollte es sein. Da wären wir wieder bei der Disziplin...
Um sicher zu gehen, dass man es eben nicht vergisst, falls es an der Disziplin hapert, sollte es "Tests" geben die einen daran erinnert.

P
660 Beiträge seit 2008
vor 10 Jahren

hallo,

ich weiss nicht ob dieser ansatz so gut ist aber du könntest ja die .cs dateien dir mittels FileStream
(StreamReader) laden, deine Methode rausextrahieren, und aus dem String dann einen hash bilden
den du dann ir wo speicherst, diesen vor dem test laden vergleichen und ggf. die ne Meldung
ausgeben lassen.

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"

1.346 Beiträge seit 2008
vor 10 Jahren

Am liebsten wäre es mir, von einer Methode einen Hash zu speichern und zur Laufzeit diesen zu vergleichen, doch ich finde keine Möglichkeit.

Die Idee finde ich interessant. Du kannst per Reflection an den Byte Code einer Methode kommen, und davon einen hash berechnen. Du kannst dir a für Tests ein Attribut schreiben mit dem aktuellen hash drin, und in dem Test prüfen, ob er noch Übereinstimmt.

An den Bytecode kommst du mit MethodInfo.GetMethodBody().GetILAsByteArray()

LG pdelvo

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Quaneu,

die Idee, zu ermitteln, ob sich eine Methode geändert hat, hat schon ihren Reiz. Allerdings kann das aus meiner Sicht nur eine zusätzliche Sicherheitsebene mit ihren eigenen Problemen sein, kein Ersatz für die von gfoidl angesprochen Ermittlung der Pfadabdeckung. Denn auch die automatische Differenzerkennung erfordert Disziplin, nämlich bei der Änderung des Tests so sorgfältig zu sein, dass auch tatsächlich alle Änderungen an der Methode berücksichtigt werden. Und du weißt ja: mit der Disziplin ist es so eine Sache. 😃

Eine weitere Herausforderung sehe ich darin, das es normalerweise keine 1:1-Beziehung zwischen Tests und getesteter Methode gibt. Für jede Methode gibt es normalerweise mehr als einen Test. Jeder einzelne Test deckt einen bestimmten Teil der zu testenden Methode ab. Wenn die Methode eine weitere Verzweigung bekommt, dann müssen die bestehenden Test oft gar nicht angepasst werden, sondern es muss nur ein weiterer Test hinzukommen.

Auch ist es andersherum nicht unbedingt so, dass ein Test immer nur genau eine Methode testet. Gerade wenn es um Protokolle geht, müssen in einem Test durchaus mehrere Methoden in einer bestimmten Reihenfolge aufgerufen werden. Und selbst wenn in dem Test nur eine Methode aufgerufen wird, wird diese doch häufig mittels Hilfsmethoden implementiert sein. Eine Änderung an einer Hilfsmethode kann das Verhalten der Methode verändern, ohne dass sich die Methode selbst geändert hat. Eigentlich müsste man also per Reflection den gesamten Aufrufbaum ermitteln und den Hash über alle beteiligten Methoden berechnen.

Selbst wenn man das alles in den Griff bekommt, bleibt noch die kleine Unschönheit, dass bei einem reinen Refactoring alle Tests der geänderten Methoden rot werden, obwohl man doch gerade möchte, dass man ein erfolgreiches Refactoring daran erkennt, dass alle Tests grün bleiben.

herbivore

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 10 Jahren

Vielen vielen Dank für eure Hilfe und Hinweise.

@pdelvo:
Klingt gut. Die Frage ist nur, ob GetILAsByteArray() das selbe liefert, wenn ich Debug oder Release eingestellt habe, bzw. wenn ich das Framework wechsle, z.B. 4.0 -> 4.5.

@herbivore:
Du hast natürlich Recht, es soll nur eine zusätzliche Ebene sein und die Leute, deren Disziplin gerade etwas "wacklig" ist daran erinnern, hier nochmal drüber zu schauen.
Mit dem Refactoring stimme ich Dir zu. Daher wären diese Tests in einem eigenen Testproject. Somit würde ich sehen, die eigentlichen Tests laufen noch und nur die Tests für die "Erinnerung" schlagen fehl.
Mit der 1:1-Beziehung muss ich nochmal nachdenken 😃, aber da hast Du auch Recht.

Vielleicht lässt es ich gar nicht, oder nicht ganz sauber umsetzten, doch ich würde so eine "Erinnerung" in manchen Fällen ganz nützlich finden.

Schöne Grüße
Quaneu