Pregunta

Últimamente he tenido que cambiar algo de código en los sistemas más antiguos, donde no todo el código ha de pruebas de unidad.
Antes de hacer los cambios que desee escribir las pruebas, pero cada clase creado un gran número de dependencias y otros anti-patrones que hizo que la prueba es muy duro.
Obviamente, quería refactorizar el código para que sea más fácil para probar, escribir las pruebas y, a continuación, cambie.
Es esta la forma en que lo podría hacer?O tendría que gastar un montón de tiempo a la redacción de la duro-a-escribir las pruebas que iba a ser eliminado en su mayoría después de la refactorización será completado?

¿Fue útil?

Solución

Primero de todo, he aquí un gran artículo con consejos sobre la unidad de pruebas.En segundo lugar, he encontrado una gran manera de evitar la toma de toneladas de cambios en el código anterior es refactorizar un poco hasta que pueda probarlo.Una manera fácil de hacer esto es hacer que los miembros privados protegidos, y luego reemplazar el campo protegido.

Por ejemplo, supongamos que tenemos una clase que carga de algunos de los contenidos de la base de datos durante el constructor.En este caso, usted no puede simplemente reemplazar un método protegido, pero puede extraer la base de datos lógica de un campo protegido y, a continuación, reemplazar en la prueba.

public class MyClass {
    public MyClass() {
        // undesirable DB logic
    }
}

se convierte en

public class MyClass {
    public MyClass() {
        loadFromDB();
    }

    protected void loadFromDB() {
        // undesirable DB logic
    }
}

y, a continuación, su prueba se ve algo como esto:

public class MyClassTest {
    public void testSomething() {
        MyClass myClass = new MyClassWrapper();
        // test it
    }

    private static class MyClassWrapper extends MyClass {
        @Override
        protected void loadFromDB() {
            // some mock logic
        }
    }
}

Esto es un poco de un mal ejemplo, porque usted podría utilizar DBUnit en este caso, pero en realidad me hizo esto en un caso similar recientemente porque quería poner a prueba algunas de las funciones totalmente ajenas a los datos cargados, por lo que era muy eficaz.También he encontrado exponiendo de los miembros para ser útil en otros casos similares en los que tengo que deshacerme de algunos de dependencia que ha estado en una clase durante un largo tiempo.

Yo recomendaría en contra de esta solución si estás escribiendo un marco pesar de que, a menos que usted realmente no le importa exponer a los miembros a los usuarios de su marco.

Es un poco de un hack, pero he encontrado que es muy útil.

Otros consejos

@valters

No estoy de acuerdo con su declaración de que las pruebas no deben romper la acumulación.Las pruebas deben ser una indicación de que la aplicación no tiene bugs nuevos introducidos por la funcionalidad que se ha probado (y un error es una indicación de una falta de prueba).

Si las pruebas no romper el construir, entonces usted puede fácilmente llegar a la situación en la que el nuevo código se rompe la generación y no se sabe para cuando, aunque una prueba de la cubría.Una prueba fallida debería ser una bandera roja que la prueba o el código tiene que ser fijo.

Por otra parte, permitir las pruebas para no romper la acumulación hará que la tasa de fracaso para lentamente hacia arriba, hasta el punto donde ya no tiene un sistema confiable de pruebas de regresión.

Si hay un problema con las pruebas de romper demasiado a menudo, puede ser una indicación de que las pruebas son escritas en demasiado frágil de una manera (la dependencia de recursos que podrían cambiar, como la base de datos sin utilizar DB Unidad de bien o un servicio web externo que debe ser burlado), o puede ser una indicación de que hay desarrolladores en el equipo que no le dan las pruebas de atención adecuada.

Creo firmemente que una de las fallas de la prueba debe ser corregido lo antes posible, tal como lo haría revisión de código que falla al compilar lo antes posible.

No estoy seguro de por qué diría usted que la unidad de pruebas se va a ser eliminado una vez que la refactorización completa.En realidad su unidad-suite de prueba se debe ejecutar después de la generación principal (se puede crear una "pruebas" construir, que sólo se ejecuta en la unidad de pruebas después de que el principal producto es construido).A continuación podrá ver inmediatamente si los cambios en una pieza de romper las pruebas en otro subsistema.La nota es un poco diferente de la ejecución de pruebas durante la construcción (como algunos pueden defensor) - algunos limitada de prueba es útil durante la construcción, pero por lo general es improductivo para "crash" de la generación porque algunos de los de la prueba de unidad pasa a fallar.

Si está escrito en Java (lo más probable), cheque hacia fuera http://www.easymock.org/ - puede ser útil para reducir el acoplamiento para los propósitos de la prueba.

He leído el Trabajo con Eficacia Con el Código Heredado, y estoy de acuerdo en que es muy útil para tratar con "inestable" de código.

Algunas técnicas sólo se aplican a los lenguajes compilados (estoy trabajando en la "vieja" aplicaciones PHP), pero yo diría que la mayoría del libro es aplicable a cualquier lenguaje.

Refactorización de libros a veces se asume que el código está en semi-ideal o "mantenimiento de cuenta" estado antes de refactorización, pero los sistemas de trabajo son menos que ideales, y se han desarrollado como "aprender sobre la marcha" de las aplicaciones, o como primer apps para algunas de las tecnologías utilizadas (y no culpo a la inicial de los desarrolladores para que, ya que yo soy uno de ellos), por lo que no hay pruebas de todo, y el código es a veces complicado.Este libro trata de este tipo de situación, mientras que otros refactorización libros generalmente no (bueno, no a esta medida).

Debo mencionar que yo no he recibido ningún dinero desde el editor ni el autor de este libro ;), pero me pareció muy interesante, ya que carecen de recursos en el campo de código heredado (y, particularmente, en mi idioma, el francés, pero esa es otra historia).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top