¿Pruebas unitarias de refactorización?

Aug 26 2020

Cuando trabajamos con código heredado y necesitamos hacer cambios, primero escribimos pruebas sobre el comportamiento actual. De esa manera podemos implementar nuevos cambios con confianza. Incluso podemos refactorizar el código.

El código heredado suele ser un código incorrecto y, después de una refactorización, el código puede ser más simple y más fácil de probar. Dado que el refactor ha sido validado por las pruebas, ¿deberíamos también refactorizar las pruebas si podemos hacerlas más simples / claras o mantenerlas como fueron escritas?

Respuestas

4 amon Aug 26 2020 at 21:49

Las pruebas automatizadas SON código, por lo que mantener este código tiene sentido, incluida la refactorización de pruebas cuando sea apropiado. Sin embargo:

  • El código productivo y las pruebas tienen diferentes requisitos de calidad.

    • no inviertas tiempo en cosas que no importan
  • El código productivo debe tener una única fuente de verdad, mientras que las pruebas deben ser en gran medida independientes

    • la duplicación no es necesariamente mala

Y como señala Ewan, nunca debe cambiar el código y las pruebas al mismo tiempo. Juntos, las pruebas de código + son un sistema de autoprueba. Un cambio en una parte se verifica ejecutándolo junto con la otra parte. Cambiar ambos al mismo tiempo renuncia a esta seguridad. Esto no siempre es posible en la práctica (por ejemplo, cuando se cambia una preocupación transversal como una biblioteca estándar subyacente), pero sería una tontería renunciar a esta seguridad sin una necesidad muy fuerte.

Razones comunes por las que he refactorizado las pruebas, sin ningún orden en particular: la API que se estaba probando había cambiado, cambiando a un enfoque de prueba diferente (por ejemplo, pruebas basadas en escenarios frente a pruebas basadas en propiedades, pruebas a nivel de API frente a pruebas a nivel de comportamiento), cambiando el marco de prueba (por ejemplo, para obtener mejores informes de fallas o para usar pruebas parametrizadas), cambiar la organización de la prueba (por ejemplo, suites y casos de estilo xUnit vs estilo RSpec describe – it), deshacerse de la duplicación acumulada (por ejemplo, extraer código común para crear un accesorio) ,…

2 DocBrown Aug 26 2020 at 21:49

Cuando trabajamos con código heredado y necesitamos hacer cambios, primero escribimos pruebas sobre el comportamiento actual. De esa manera podemos implementar nuevos cambios con confianza. Incluso podemos refactorizar el código.

Eso puede estar reflejando a veces su proceso de trabajo, pero en mi experiencia, un proceso más eficiente es:

  1. tu escribes pruebas

  2. refactorizas para facilitar el cambio

  3. implementas el cambio

De esta manera, se hace más evidente que refactoriza cuando hay una razón real para un cambio , no solo porque el código "ya no está limpio".

Ahora intente aplicar las mismas medidas a sus pruebas: no refactoriza sus pruebas porque "ya no están limpias" . Los refactoriza cuando comienzan a obstaculizarlo para realizar cambios fáciles en su código existente.

Por ejemplo, cuando tiene diez pruebas que llaman todas al mismo método público de una clase bajo pruebas, mientras que en su código de producción ese método público solo se llama en un lugar, entonces esta es una forma de duplicación de código mediante pruebas que puede obstaculizarlo cambiar la firma de ese método público.

Por lo general, lo dejaría así a menos que realmente obtenga el requisito para este último, o de manera más general: cuando observe que esta duplicación de código requiere que realice el mismo cambio en sus pruebas en varios lugares.

null Aug 27 2020 at 15:12

Es posible que desee comenzar con la refactorización de las pruebas.

Las pruebas capturan lo que hace la aplicación heredada; una especie de documentación. Las pruebas le indican la entrada y la salida, el código le indica el proceso. Si las pruebas son malas, ordenarlas (dependiendo de qué tan malas sean) le ayudará a comprender el código.

También es una excelente manera de juzgar si las pruebas agregan valor; un sistema heredado en el que trabajé tenía una gran cobertura de código, pero en la inspección, las pruebas afirmaron cosas sin sentido ... como asegurarse de que Getters y Setters funcionaran (probar el marco .NET, no la aplicación).

Una vez que haya obtenido una prueba limpia, comprenderá mejor el código y luego podrá tomar mejores decisiones sobre cómo refactorizar el código.