Hashcodes & Unittests

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

Dieses ist keine (direkte) Frage sondern ein Abstecher des Themas "nach serializability bzw immutability fragen" (ich weiß nicht, wie man einen Link setzt); der ursprüngliche Thementitel dort passt gar nicht mehr zu einigen der letzten Beiträge.

Zur Erinnerung:
Ich überschreibe den Hashcode einiger meiner großen Objekte, um ihn für Unittests zu benutzen. Der ursprüngliche Hashcode ist dafür unbrauchbar, da er anscheinend nur die Speicheradresse des Objekts umformt (kann man leicht testen, indem man das Programm verschiedene Male aufruft). Damit der neue Hashcode für Unittests zu gebrauchen ist, muss ich natürlich wissen, wann er vom jeweiligen Rechenlauf abhängt und wann er unveränderlich ist.

mutetella hat geschrieben:Kannst Du mir vielleicht einmal ein konkretes Beispiel eines solchen Objektes oder eines seiner Attribute geben?
Der Suchbaum einer Branch-and-Bound-Suche nach 20 Suchschritten. So ein B&B-Suchbaum kann nicht nur sehr groß sein, sondern hat auf jedem seiner Knoten auch noch verschachtelte Listen und massenweise andere Attribute. So ein Suchbaum ist natürlich nur ein Zwischenergebnis zur Lösung der Aufgabe, aber für meine Unittests muss ich gerade die Zwischenergebnisse überprüfen, da die Endlösung viel zu wenig über den Code eines einzelnen Moduls aussagt.
anogayales hat geschrieben:Was machst du wenn der Unit Test fehlschlägt? Dann weißt du ja nur, dass es irgendwo eine Diskrepatz gibt, aber nicht notwendigerweise wo. Bei einer so großen Menge an Daten wird dir das doch wenig weiterbringen, oder?
Bei so langen Berechnungen sollte man den Test vielleicht nicht Unittest, sondern "Pakettest" nennen. Ich kenne das richtige Ergebnis nicht und dessen Berechnung ist bei weitem zu lang, um sie von Hand durchzuführen. Ich habe also kaum eine Alternative. Bei Diskrepanzen müssen die Fehler sowohl beim alten als auch wie beim neuen Code gesucht werden; das verdoppelt die Arbeit. Aber es ist weniger dramatisch als es aussieht, da man den Pakettest bei jeder Codeänderung aufruft und der Fehler oft (leider nicht immer) mit der letzten Änderung zu tun hat.
Zuletzt geändert von Goswin am Mittwoch 26. Oktober 2011, 11:12, insgesamt 2-mal geändert.
BlackJack

@Goswin: Mein erster Ansatz wäre hier die Objekte zu Picklen und `__eq__()` oder `__cmp__()` zu implementieren, statt `__hash__()`. Dann kannst Du sie entpickeln und ganz einfach vergleichen, statt einen Hash zu berechnen, der in ganz ungünstigen Fällen doch eine Kollision aufweisen könnte. `__hash__()` sollte man dann natürlich trotzdem zusätzlich implementieren oder zumindest eine Ausnahme auslösen lassen.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:Mein erster Ansatz wäre hier die Objekte zu Picklen und `__eq__()` oder `__cmp__()` zu implementieren, statt `__hash__()`. Dann kannst Du sie entpickeln und ganz einfach vergleichen, statt einen Hash zu berechnen
Kann ich mir mit einer Hash-Implementierung nicht die wiederholte Entpickelung einsparen, indem ich die Hashzahl des (soweit) bewährten Objektes nur einmal berechne und dann der Unittest-Funktion als Parameter übergebe (oder sie ggf hart hineincodiere)?
BlackJack

@Goswin: Die wiederholte Entpicklung kannst Du Dir auch sparen, in dem Du es einfach nicht wiederholt entpicklest. Andererseits wäre das sicherer um ausschliessen zu können, dass beim Test etwas am Objekt verändert wurde.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@BlackJack:
Alles klar. Ich gebe zu, dass ich fuer die Hash-Überschreibung außer der oben beschriebenen noch andere Anwendungen im Kopf hatte.
Antworten