Bonjour,
je suis en train de créer un outil qui utilise selenium pour faire des tests. Dans le cadre de cet outil, je voudrais ajouter un certains nombres de fonctionnalités qui peuvent se passer lors du succès ou de l'échec du test.
Ces opérations sont configurables statiquement, c'est à dire qu'on peut –par classe de test– définir les opérations qui seront réalisées ou non.
Pour faire simple, on se réduira pour l'instant à une seule opération : la prise de screenshot, qu'on peut coder ainsi :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class TestCallback: """ This represent action that will be executed at the end of a test """ def on_success(self, test): pass def on_failure(self, test): pass def on_error(self, test): pass def on_skip(self, test): pass class TakeScreenshotCallback(TestCallback): def __init__(self, filepath_format): self.filepath_format = filepath_format def on_failure(self, test): if hasattr(test, "driver"): test.driver.save_screenshot(self.filepath_format.format(**{ "time": int(time.time()), "name": test.__class__.__name__, "status": "fail" })) def on_error(self, test): if hasattr(test, "driver"): test.driver.save_screenshot(self.filepath_format.format(**{ "time": int(time.time()), "name": test.id(), "status": "fail" |
Seulement voilà, j'aimerai pouvoir ajouter facilement cette capacité à mes tests.
Bien que je n'ai qu'une maîtrise relative du concept, j'ai (peut être trop) rapidement pensé aux décorateurs, mon idée serait alors de dire :
1 2 3 4 | @with_callback(TakeScreenshotCallback("/var/log/screenshots/{name}.png")) class MonTest(TestSelenium): def test_smth(self): pass |
Sachant que la classe TestSelenium
est liée à une instance de TestResult qui s'assure qu'on a bien un appel aux callbacks.
Actuellement, mon décorateur ressemble à ce qui suit :
1 2 3 4 5 6 7 8 | def with_callback(cls, callback): class NewTest(cls): def __init__(self, *args, **kwargs): super(NewTest, self).__init__(*args, **kwargs) if not getattr(self, "callbacks"): self.callbacks = [] self.callbacks.append(callback) return NewTest |
Seul problème : quand je fais @with_callback(TakeScreenshotCallback("/var/log/screenshots/{name}.png"))
, python m'engueule car en donnant un argument à with_callback.
Ma question est donc : comment régler ce problème? Est-ce au moins possible avec les décorateurs? Est-ce au moins souhaitable de le faire avec des décorateurs? Toute autre idée m'intéresse.