Ich schreibe einen kleinen Job-Scheduler in Python. Der Scheduler kann eine Reihe von Callables plus Abhängigkeiten erhalten und sollte die Callables ausführen, um sicherzustellen, dass keine Task vor einem seiner Vorgänger ausgeführt wird.Testen einer Funktion, die nicht-deterministische Ergebnisse mit Python Unit Test zurückgeben kann
Ich versuche, einen Test-driven Ansatz zu folgen, und ich bin in ein Problem getestet, das Abhängigkeitshandhabung prüft. Mein Test-Code sieht wie folgt aus:
def test_add_dependency(self):
"""Tasks can be added with dependencies"""
# TODO: Unreliable test, may work sometimes because by default, task
# running order is indeterminate.
self.done = []
def test(id):
self.done.append("Test " + id)
s = Schedule()
tA = Task("Test A", partial(test, "A"))
tB = Task("Test B", partial(test, "B"))
s.add_task(tA)
s.add_task(tB)
s.add_dependency(tA, tB)
s.run()
self.assertEqual(self.done, ["Test B", "Test A"])
Das Problem ist, dass dieser Test (manchmal) arbeitete, noch bevor ich die Abhängigkeit Behandlungscode hinzugefügt. Dies liegt daran, dass die Spezifikation nicht angibt, dass Aufgaben in einer bestimmten Reihenfolge ausgeführt werden müssen. Daher ist die richtige Reihenfolge eine vollkommen gültige Wahl, selbst wenn die Abhängigkeitsinformation ignoriert wird.
Gibt es eine Möglichkeit, Tests zu schreiben, um diesen "zufälligen" Erfolg zu vermeiden? Es scheint mir, dass dies eine ziemlich häufige Art von Situation ist, insbesondere wenn man den Test-getriebenen Ansatz "Schreibe keinen Code ohne einen fehlgeschlagenen Test" anwendet.
Ich kenne Scheduler, die absichtlich eine Randomisierung verwenden (normalerweise eingeschaltet durch ein "Testmodus" -Flag), wenn eine von vielen möglichen Auswahlen ausgewählt wird. Damit könnten Sie Ihren Test einige Male durchführen und prüfen, ob * alle * Ergebnisse korrekt sind. Dies ist jedoch keine echte Lösung, da Sie nie wissen, wie viele Runden Sie benötigen. – rainer
Obwohl Vorschläge für Tests sehr nützlich sind, denke ich, dass mein wirkliches Problem in der "testgetriebenen" Idee liegt, dass ich keinen Code schreiben sollte, wenn ich keinen fehlerhaften Test habe. In diesem Fall hinterlässt die Spezifikation bewusst ein Maß an Flexibilität, das das Schreiben eines solchen Tests unmöglich macht. Dies ist immer, wo ich mit dem Test-getriebenen Ansatz festhalte, aber normalerweise bin ich nur zu faul, um einen guten Test zu schreiben, nicht weil ich nicht kann :-) –