Est-il bon ou mauvais de dupliquer les données entre les tests et le vrai code? Par exemple, supposons que j'ai une classe Python FooSaver
qui enregistre des fichiers avec des noms particuliers dans un répertoire donné:
class FooSaver(object):
def __init__(self, out_dir):
self.out_dir = out_dir
def _save_foo_named(self, type_, name):
to_save = None
if type_ == FOOTYPE_A:
to_save = make_footype_a()
elif type == FOOTYPE_B:
to_save = make_footype_b()
# etc, repeated
with open(self.out_dir + name, "w") as f:
f.write(str(to_save))
def save_type_a(self):
self._save_foo_named(a, "a.foo_file")
def save_type_b(self):
self._save_foo_named(b, "b.foo_file")
Maintenant, dans mon test, je voudrais m'assurer que tous ces fichiers ont été créés, donc je veux dire quelque chose comme ceci:
foo = FooSaver("/tmp/special_name")
foo.save_type_a()
foo.save_type_b()
self.assertTrue(os.path.isfile("/tmp/special_name/a.foo_file"))
self.assertTrue(os.path.isfile("/tmp/special_name/b.foo_file"))
Bien que cela duplique les noms de fichiers à deux endroits, je pense que c'est bien: cela m'oblige à écrire exactement ce que j'attends à l'autre bout, il ajoute une couche de protection contre les fautes de frappe et me donne généralement confiance que les choses fonctionnent exactement comme je l'attends. Je sais que si je passe a.foo_file
à type_a.foo_file
l'avenir, je vais devoir faire des recherches et des remplacements dans mes tests, mais je ne pense pas que ce soit trop important. Je préfère avoir des faux positifs si j'oublie de mettre à jour le test en échange de m'assurer que ma compréhension du code et des tests est synchronisée.
Un collègue pense que cette duplication est mauvaise et a recommandé que je refactorise les deux côtés à quelque chose comme ceci:
class FooSaver(object):
A_FILENAME = "a.foo_file"
B_FILENAME = "b.foo_file"
# as before...
def save_type_a(self):
self._save_foo_named(a, self.A_FILENAME)
def save_type_b(self):
self._save_foo_named(b, self.B_FILENAME)
et dans le test:
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.A_FILENAME))
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.B_FILENAME))
Je n'aime pas cela parce que cela ne me donne pas confiance que le code fait ce que j'attendais --- Je viens de dupliquer l' out_dir + name
étape à la fois du côté de la production et du côté du test. Il ne découvrira pas une erreur dans ma compréhension du +
fonctionnement des chaînes et n'attrapera pas les fautes de frappe.
D'un autre côté, c'est clairement moins fragile que d'écrire deux fois ces chaînes, et il me semble un peu mal de dupliquer des données sur deux fichiers comme ça.
Y a-t-il un précédent clair ici? Est-il correct de dupliquer des constantes entre les tests et le code de production, ou est-ce trop fragile?