Quizás el problema no radique en la mejor manera de escribir docstrings de prueba, ¿pero cómo escribir las pruebas por sí mismos? Refactorizar las pruebas de forma tal que sean auto documentadas puede ser de gran ayuda, y su docstring no se quedará obsoleto cuando cambie el código.
Hay algunas cosas que usted puede hacer para hacer las pruebas más claras:
- claras & nombres de los métodos de prueba descriptiva (ya mencionado)
- cuerpo de prueba debe ser clara y concisa (autodocumentado)
- resumen la configuración/desmontaje complicado etc. en los métodos
- más?
Por ejemplo, si tiene una prueba como esta:
def test_widget_run_returns_0():
widget = Widget(param1, param2, "another param")
widget.set_option(true)
widget.set_temp_dir("/tmp/widget_tmp")
widget.destination_ip = "10.10.10.99"
return_value = widget.run()
assert return_value == 0
assert widget.response == "My expected response"
assert widget.errors == None
Es posible reemplazar las instrucciones de configuración con una llamada al método:
def test_widget_run_returns_0():
widget = create_basic_widget()
return_value = widget.run()
assert return_value == 0
assert_basic_widget(widget)
def create_basic_widget():
widget = Widget(param1, param2, "another param")
widget.set_option(true)
widget.set_temp_dir("/tmp/widget_tmp")
widget.destination_ip = "10.10.10.99"
return widget
def assert_basic_widget():
assert widget.response == "My expected response"
assert widget.errors == None
nota de que su método de ensayo se compone ahora de una serie de llamadas a métodos con nombres reveladores de intenciones, una especie de DSL específico para sus pruebas. ¿Una prueba como esa todavía necesita documentación?
Otra cosa a tener en cuenta es que su método de prueba se basa principalmente en un nivel de abstracción. Alguien que lee el método de prueba será ver el algoritmo es:
- crear un widget
- llamando corrida en el widget
- hacer valer el código hizo lo que esperamos
Su comprensión del método de ensayo no está enredado por los detalles de la configuración del widget, que es un nivel de abstracción menor que el método de prueba.
La primera versión del método de prueba sigue el patrón Inline Setup. La segunda versión sigue los patrones Creation Method y Delegated Setup.
Generalmente estoy en contra de los comentarios, excepto cuando explican el "por qué" del código. La lectura del Clean Code del tío Bob Martin me convenció de esto. Hay un capítulo sobre comentarios, y hay un capítulo sobre pruebas. Lo recomiendo.
Para obtener más información sobre las mejores prácticas de pruebas automáticas, consulte xUnit Patterns.
¿Qué pasa con los nombres de sus funciones?Supongo que nombre sus pruebas "testFunctionName" y eso está bien, ¿pero realmente tiene una función llamada InitializeSetsUpChessBoardCorrectly? Creo que "setUpChessboard" estaría bien. –
No, el nombre del método explica exactamente lo que está probando: el caso de prueba verifica que initalize() configura correctamente el tablero de ajedrez. Boom, documentación automática. –
Jaja, sí, la "prueba" al principio es solo de los viejos tiempos de JUnit, que mi cerebro todavía está atrapado. Podría simplemente nombrarlo initalizeSetsUpChessBoardCorrectly() y usar una anotación @Test. –