2011-12-06 19 views
6

Hace poco se unió a una empresa en la que usan TDD, pero todavía no está claro para mí, por ejemplo, tenemos una prueba:¿Por qué esta prueba en particular podría ser útil?

[TestMethod] 
public void ShouldReturnGameIsRunning() 
{ 
    var game = new Mock<IGame>(); 
    game.Setup(g => g.IsRunning).Returns(true); 
    Assert.IsTrue(game.Object.IsRunning); 
} 

¿Cuál es la finalidad de la misma? Por lo que yo entiendo, ¡esto no prueba nada! Lo digo porque se burla de una interfaz, y diciendo, devuelve true para IsRunning, nunca devolverá un valor diferente ...

Probablemente estoy pensando mal, ya que todo el mundo dice que es una buena práctica, etc. o esta prueba es incorrecta?

+3

Por lo general, no son restos este sentido. – sarnold

+3

Tienes dos cosas diferentes en juego en esta pregunta: "¿Cuál es el propósito de TDD?" y "¿Cuál es el objetivo de esta prueba?" - Tenga cuidado de mantener los dos separados en su propia cabeza. El valor (o no) de TDD no puede juzgarse de manera justa a partir de una única prueba (posiblemente deficiente). – Bevan

+0

Ojalá pudiera cerrar esto como un duplicado de http://stackoverflow.com/questions/tagged/tdd?sort=votes&pagesize=50 –

Respuesta

5

La prueba no es válida. Moq es un marco utilizado para "simular" objetos utilizados por el método bajo prueba. Si estaba probando IsRunning, puede usar Mock para proporcionar una cierta implementación para los métodos de los que depende IsRunning, por ejemplo, para ejecutar ciertas rutas de ejecución.

Las personas pueden decirle todo el día que primero las pruebas son mejores; no se dará cuenta de que realmente es así hasta que empiece a hacerlo usted mismo y se dé cuenta de que tiene menos errores con el código para los que escribió pruebas primero, lo que le ahorrará tiempo a usted y a sus compañeros de trabajo y probablemente aumentará la calidad de su código.

+0

hmm Sospeché que ... hay una implementación de la interfaz IGame que no se ha probado en absoluto, es por eso que no entiendo la idea de esto ... – user1082693

+0

no hay sentido de tener otra implementación de la interfaz IGame, deberían probar el objeto Game en lugar de la interfaz, ¿verdad? ¿Qué hay de conducir el diseño del código? Quiero decir, ¿cómo debería definir que debe haber una propiedad IsRunning? – user1082693

+0

@ user1082693: Correcto. Ahora bien, si estuvieras probando el comportamiento de un método basado en ciertos valores de retorno de los métodos de 'IGame', Moq ciertamente sería útil: crear una subclase completamente nueva de 'IGame' solo con fines de prueba resultaría dolorosa. En cuanto a las pruebas para una propiedad determinada, permitiría que construcciones de código como interfaces y clases abstractas hagan cumplir esas reglas. –

3

Podría ser que la prueba haya sido escrita (antes) con el código que es una buena práctica.

También podría ser que esta es una prueba sin sentido creada por una herramienta.

+0

No creo que haya ninguna herramienta que cree la prueba aquí, por lo que es probable que hayan escrito la prueba antes del código ... hmmm – user1082693

+6

¡Depende de tu definición de "herramienta"! :) – griegs

+3

+1 y podríamos referirnos al significado popular de la palabra "herramienta";) –

6

Esta prueba consiste en una interfaz y verifica que la interfaz expone un captador booleano llamado IsRunning.

Esta prueba probablemente se escribió antes de que existiera el interface, y probablemente mucho antes de que existieran clases concretas de IGame. Me imagino que, si el proyecto es de alguna madurez, existen otras pruebas que ejercen las implementaciones reales y verifican el comportamiento para ese nivel, y probablemente usan la burla en el contexto aislacionista más tradicional en lugar de anotar las formas teóricas.

El valor de este tipo de pruebas es que obliga a pensar cómo se va a utilizar una forma u objeto. Algo así como "No sé exactamente qué va a hacer un juego todavía, pero sí sé que voy a querer comprobar si se está ejecutando ...". Por lo tanto, este estilo de prueba es más para impulsar las decisiones de diseño, así como para validar el comportamiento.

No es la prueba más valiosa del planeta, pero cumple su función en mi opinión.

Editar: Yo estaba en el tren anoche cuando estaba escribiendo esto, pero quería dirigirme a Andrew Whitaker para comentar directamente en la respuesta.

Se podría argumentar que la firma en la interfaz en sí es suficiente para hacer cumplir el contrato deseado. Sin embargo, esto realmente depende de cómo trate sus interfaces y, finalmente, de cómo valide el sistema que está tratando de probar.

Puede haber un valor tangible al declarar explícitamente esta funcionalidad como una prueba. Está verificando explícitamente que esta es una funcionalidad deseada para un IGame.

Tomemos un caso de uso, digamos que como diseñador sabe que quiere exponer un getter público para IsRunning, por lo que lo agrega a la interfaz.Pero digamos que otro desarrollador obtiene esto y ve una propiedad, pero no ve ningún uso de ella en ningún otro lugar en el código, se puede suponer que es elegible para eliminación (o eliminación de eliminación de código, que normalmente es algo bueno)) sin daño La existencia de esta prueba, sin embargo, establece explícitamente que esta propiedad debería existir.

Sin esta prueba, un desarrollador podría modificar la interfaz, abandonar la implementación y el proyecto aún se compilaría y ejecutaría aparentemente correctamente. Y sería hasta mucho después que alguien note que la interfaz ha cambiado.

Con esta prueba, aunque parezca que nadie está usándola, su conjunto de pruebas fallará. La naturaleza autodocumentada de la prueba indica que ShouldReturnGameIsRunning(), que al menos debe engendrar una conversación si IGame realmente expone un getter IsRunning.

+1

genial Lo entiendo ... Los preguntaré mañana, así que probablemente debería ser para conducir el diseño, y luego debería crear más pruebas para probar la lógica, ¿no? – user1082693

+0

@ 32bitkid: Esto podría ser solo mi opinión, ¿pero no es una prueba exagerada para esto?¿No sería simplemente definir una firma para el método en la interfaz crear el "contrato" que esta prueba está probando? –

+1

@AndrewWhitaker. Creo que depende de cómo pienses sobre la validación del sistema que estás tratando de probar. Puede haber algún valor al afirmar explícitamente esto como una prueba de que esta es una funcionalidad deseada para un 'IGame'. Si solo fuera una firma, si en un uso, en cualquier lugar, puede parecer que podría eliminarse sin daño. Esta prueba establece explícitamente que esta propiedad debería existir. Si no lo hace, incluso si nadie lo utiliza, sus pruebas fallarán –

1

Otra posibilidad es que el código fue escrito por alguien que, en ese momento, no entendía cómo usar ese marco burlón particular, y escribió una o más pruebas simples para aprender. Kent Beck habló sobre ese tipo de "prueba de aprendizaje" en su libro TDD original.

0

Esta prueba podría haber tenido un punto en el pasado. Podría haber estado probando una clase concreta. Podría haber estado probando uno abstracto, ya que a veces tiene sentido burlarse de una clase abstracta que desea probar. Puedo ver cómo un (menos informado (como yo)) seguidor de la forma TDD de hacer las cosas podría haber dejado un pequeño desastre como este. La limpieza del código muerto y del código de prueba muerto, no encaja realmente en el flujo de trabajo natural del refactor rojo, verde (¡ya que no interrumpe ninguna prueba!). Sin embargo, la historia no justifica una prueba que no hace más que confundir al lector. Entonces, sé un buen boyscout y quítalo.

0

en mi opinión honesto, esto es sólo basura, que sólo demuestra que moq funciona como se espera

Cuestiones relacionadas