¿Es bueno o malo duplicar datos entre pruebas y código real? Por ejemplo, supongamos que tengo una clase Python FooSaver
que guarda archivos con nombres particulares en un directorio dado:
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")
Ahora, en mi prueba, me gustaría asegurarme de que todos estos archivos fueron creados, así que quiero decir algo como esto:
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"))
Aunque esto duplica los nombres de archivo en dos lugares, creo que es bueno: me obliga a escribir exactamente lo que espero que salga al otro lado, agrega una capa de protección contra errores tipográficos y, en general, me hace sentir seguro de que las cosas están funcionando exactamente como lo espero. Yo sé que si cambio a.foo_file
a type_a.foo_file
en el futuro voy a tener que hacer un poco de búsqueda y reemplazo en mis pruebas, pero no creo que es demasiado grande de un acuerdo. Prefiero tener algunos falsos positivos si me olvido de actualizar la prueba a cambio de asegurarme de que mi comprensión del código y las pruebas estén sincronizadas.
Un compañero de trabajo piensa que esta duplicación es mala y me recomendó refactorizar ambos lados para hacer algo como esto:
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)
y en la prueba:
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.A_FILENAME))
self.assertTrue(os.path.isfile("/tmp/special_name/" + FooSaver.B_FILENAME))
No me gusta esto porque no me hace confiar en que el código está haciendo lo que esperaba --- Acabo de duplicar el out_dir + name
paso tanto en el lado de la producción como en el lado de la prueba. No descubrirá un error en mi comprensión de cómo +
funciona en las cadenas, y no detectará errores tipográficos.
Por otro lado, es claramente menos frágil que escribir esas cadenas dos veces, y me parece un poco incorrecto duplicar datos en dos archivos como ese.
¿Hay un precedente claro aquí? ¿Está bien duplicar constantes en las pruebas y el código de producción, o es demasiado frágil?
fuente