2009-04-08 8 views
7

Estoy tratando de familiarizarme con la metodología TDD y me he topado con lo que creo que es un problema de gallina y huevo: qué hacer si una solución de error implica el cambio de la firma de un método.Cómo usar TDD cuando la solución implica cambiar el método bajo la firma de la prueba?

Consideremos el siguiente método de firma:

string RemoveTokenFromString (string delimited, string token) 

Como el nombre sugiere, este método elimina todas las instancias de un token de delimited y devuelve la cadena resultante.

Encuentro más tarde que este método tiene un error (por ejemplo, se están eliminando los bits incorrectos de la cadena). Así que escribo un caso de prueba que describe el escenario donde ocurre el error y me aseguro de que la prueba falla.

Al solucionar el error, encuentro que el método necesita más información para poder hacer su trabajo correctamente, y este fragmento de información solo se puede enviar como parámetro (el método bajo prueba es parte de una clase estática)

¿Qué hago entonces? Si soluciono el error, esto me obliga a cambiar la prueba unitaria. ¿Sería eso una metodología TDD "correcta"?

Respuesta

5

No hay absolutamente nada de malo en bombardear sus pruebas, cuando descubre que el comportamiento previsto de la unidad cambia.

//Up front 
[Test] 
public void should_remove_correct_token_from_string() 
{ 
    var text = "do.it.correctly.."; 
    var expected = "doitcorrectly"; 
    Assert.AreEqual(StaticClass.RemoveTokenFromString(text, "."), expected); 
} 

//After finding that it doesn't do the right thing 
//Delete the old test and *design* a new function that 
//Does what you want through a new test 
//Remember TDD is about design, not testing! 
[Test] 
public void should_remove_correct_token_from_string() 
{ 
    var text = "do.it.correctly.."; 
    var expected = "doitcorrectly"; 
    Assert.AreEqual(
     StaticClass.RemoveTokenFromString(
      text, 
      ".", 
      System.Text.Encoding.UTF8), expected); 
} 

//This will force you to add a new parameter to your function 
//Obviously now, there are edge cases to deal with your new parameter etc. 
//So more test are required to further design your new function 
1

rojo, verde, Refactor.

Hagas lo que hagas, primero quieres llegar a un estado en el que tengas un caso de prueba de compilación pero deficiente que reproduzca el error. A continuación, puede continuar agregando solo el parámetro a la prueba y la implementación, pero no haga nada con eso, de modo que aún tenga Red.

0

Si un método no está haciendo el trabajo correctamente, entonces necesita ser reparado y si el arreglo requiere un cambio en la firma, entonces notará que está equivocado. De acuerdo con TDD, primero escribe el caso de prueba, que seguramente fallará y luego escribe el método para satisfacer la prueba. Según este enfoque, si la prueba de llamada del método requiere un parámetro para que funcione, entonces debe hacerlo.

2

Hay una refactorización llamada Add Parameter que podría ayudar aquí.

Si su idioma es compatible con method overloading, primero puede crear la nueva función con el nuevo parámetro, copiando el cuerpo de la función existente y solucionando su problema.

Luego, cuando se resuelva el problema, puede modificar todas las pruebas, una por una, para llamar al nuevo método. Por último, puedes eliminar el método anterior.

Con un lenguaje que no admite métodos de sobrecarga, cree una nueva función con un nombre diferente, copie el cuerpo en la función existente en esa nueva función, haga que la función existente invoque la nueva función, posiblemente con un valor ficticio para el nuevo parámetro. Entonces podrías pasar todas tus pruebas. Haga que sus pruebas antiguas llamen a la nueva función, una por una. Cuando el método anterior ya no se utiliza, se puede eliminar y renombrar la nueva función.

Esto es un proceso un poco extenso, pero creo que es la forma TDD de seguir rojo-verde-refactor.

El valor predeterminado para el parámetro también podría ayudar, si hay disponibles.

4

Hazlo simple.

Si la prueba de su unidad es incorrecta u obsoleta, debe volver a escribirla. Si sus especificaciones cambian, o ciertas especificaciones ya no son relevantes, las pruebas de su unidad tienen que reflejar eso.

rojo, verde, refactor también se aplica a las pruebas de su unidad, no solo al código que está probando.

+0

Amen a eso, bien dicho. –

1

Yo diría que no te preocupes por la forma "correcta"/"correcta" ... lo que sea que te ayude a acercarte más rápido a la solución.

Si usted encuentra que usted necesita tomar en un parámetro adicional,

  • actualización de la llamada en el caso de prueba
  • añadir el nuevo parámetro para el método real
  • comprobar que el código construye y la prueba falla nuevamente
  • proceden a hacerlo verde.

Solo en los casos en que agregar un nuevo parámetro resultaría en trillones de errores de compilación, lo recomendaría, en pequeños pasos ... no quiere actualizar toda la base de datos antes de descubrir que realmente no lo hizo Necesito el tercer parámetro o necesitas un cuarto ... tiempo perdido. Así que obtenga la nueva versión del método 'funcionando' antes de actualizar todas las referencias. (Como Philippe dice aquí)

  • escribir una nueva sobrecarga con el parámetro añadido
  • mover el código del método antiguo en el nuevo sobrecarga
  • Hacer el relé de sobrecarga de edad o delegar en el nuevo sobrecarga con alguna valor predeterminado para el nuevo parámetro
  • Ahora puede volver a la tarea en cuestión y hacer que la nueva prueba se vuelva verde.
  • Si ya no necesita la antigua sobrecarga, elimínela y solucione los errores de compilación resultantes.
+0

Excelente respuesta :) – Mik378

5

Ha caído en la trampa más peligrosa de TDD: cree que TDD se trata de pruebas, pero no lo es. Sin embargo, es fácil caer en esa trampa, ya que toda la terminología en TDD se trata de pruebas. Esta es la razón por la cual BDD fue inventado: es esencialmente TDD, pero sin la terminología confusa.

En TDD, las pruebas no son realmente pruebas, son ejemplos. Y las afirmaciones no son realmente afirmaciones, son expectativas. Y no se trata de unidades, se trata de comportamientos. BDD simplemente los llama así. (Nota: BDD ha evolucionado desde que se inventó por primera vez, y ahora incorpora cosas que no son parte de TDD, pero la intención original era simplemente que "muchas personas hacen TDD incorrectamente, así que use palabras diferentes para ayudarlo a hacerlo bien".

De todos modos, si piensas en una prueba no como una prueba, sino como un ejemplo de comportamiento de cómo debería funcionar el método, debería ser obvio que a medida que desarrollas una mejor comprensión del comportamiento esperado, elimina o cambia la prueba no solo está permitido por TDD, ¡es la única elección correcta! ¡Siempre mantén eso en mente!

+0

+50 votos virtuales para ti :) – Mik378

Cuestiones relacionadas