2011-05-01 19 views
12

¿Cuál es la recomendación de mejores prácticas para realizar TDD con contratos de código de .NET 4.0?Cómo realizar pruebas unitarias con Contratos de código

Supongo que específicamente, dado que un punto de TDD es permitir que el código sea auto documentado y el contrato ahora proporciona una parte de la documentación, si los contratos de código se prueban de la misma manera que otros códigos ?

Respuesta

11

Esto depende de cómo utiliza los contratos y qué tipo de aplicación está desarrollando.

En primer lugar: Por cierto, no quiere poner a prueba las afirmaciones y condiciones posteriores (Contract.Assert, Contract.Assume, Contract.Ensures y Contract.EnsuresOnThrow) separetly. No veo ningún valor práctico al hacerlo, ya que el regrabador ya lo ha verificado durante el tiempo de ejecución, encontrará fallas muy rápidas incluso sin pruebas.
Sin embargo, en una aplicación bien probada, ninguna condición o afirmación debe fallar, incluso en entradas no válidas. Por lo tanto, si todas sus pruebas (¡incluso las que prueban el manejo de datos no válidos!) Pasan sin que una sola postcondición/afirmación falle, sus postcondiciones y aserciones pueden verse como "probadas".
Para esto, es posible que desee manejar el evento ContractFailed utilizando un "Assert.Fail" dentro de sus pruebas.

Ahora la parte "interesante" son las condiciones previas:
¿Está desarrollando una biblioteca? Entonces, definitivamente debe probarlos si su tiempo/presupuesto lo permite (es peor no probar la lógica real).
Especialmente, si está utilizando la sobrecarga "Contract.Requires <E>" que arrojará una excepción específica en las fallas de contrato, debe probarlas como la validación de parámetros regulares usando "if-throw" -constructs.

Si no está escribiendo una biblioteca, no diría que las condiciones previas de prueba son realmente necesarias; no son un requisito comercial real sino más bien un ayudante para la depuración.
Y puede ser realmente aburrido escribir una prueba unitaria por cada ArgumentNullException que un método debería arrojar si un parámetro es null.
Si olvida este código de validación (es decir, el Contrato específico requerido) dentro de su método, probablemente también se olvide de la prueba de unidad. Por lo tanto, el valor adicional que un parámetro-validación-prueba aporta a su código (no de biblioteca) es muy bajo para el valor conectado.

Resumiendo: No pruebe las postcondiciones y afirma. Pruebe las condiciones previas, pero solo en las bibliotecas (y tal vez en partes de su código que se utilizan como bibliotecas).

+0

"No te compruebe las condiciones y afirmaciones. Pruebe las condiciones previas, pero solo en las bibliotecas (y tal vez en partes de su código que se utilizan como bibliotecas). - suena como un consejo bastante decente: ¿se basa en tu propia experiencia o en la sabiduría recibida? – briantyler

+0

+1 para el gran resumen! – koenmetsu

+0

@B Tyler: Se basa en mi experiencia y discusión con otros programadores. Sin embargo, sigue siendo solo mi opinión y no está respaldado por ningún estudio o investigación a largo plazo ;-) – Matthias

1

Una gran pregunta. La respuesta simple es no. los contratos de código pueden encargarse de las pruebas superfluas que no se refieren al comportamiento del sistema. Si realmente puede obtener una cobertura del 100% del código, tendrá que encargarse de los controles ininteligibles, etc. estos controles no necesitan estar en su banco de pruebas. el beneficio adicional es que estos se verificarán en tiempo de compilación en lugar de esperar a que se ejecuten las pruebas.

Espero que esto ayude.

1

Una herramienta útil para crear pruebas unitarias en combinación con Contratos de código es Pex. Analiza su código y genera pruebas básicas de la unidad para ello. Lo mejor es que reconoce y entiende los contratos de código, y por lo tanto adapta el código de prueba que genera.

Si tiene una suscripción a MSDN, puede descargar Pex/Moles como herramienta de poder, de lo contrario puede descargarla (no la versión más reciente) en http://research.microsoft.com/en-us/projects/pex/downloads.aspx.

3

No estoy de acuerdo con otras personas aquí. Los contratos NO son pruebas, son afirmaciones sobre los requisitos y promesas de la API. No prueban mágicamente que tu código sea correcto, solo te brindan información en tiempo de ejecución cuando violas el contrato. No sé ustedes, pero odiaría enviar código que en algún rincón, el caso no cumplía con los contratos y se bloqueaba con una afirmación de contrato. Al igual que cualquier otro comportamiento, los contratos deben someterse a pruebas unitarias. Si no ejerce los contratos (y rutas de código que indirectamente ejercen los contratos) no tiene evidencia de la validez de los códigos. Los contratos de código y las pruebas unitarias no son conceptos mutuamente excluyentes.

+1

No son * solo * información de tiempo de ejecución; también se puede realizar la verificación estática que causa errores en el tiempo de compilación (por ejemplo, cuando se llama a un método con un parámetro que podría ser nulo pero el contrato requiere que no lo sea). – TheXenocide

0

Las pruebas están ahí para probar el código se comporta como se esperaba

NO debe explicitamente escribir pruebas para ejercer las afirmaciones del contrato.

Sin embargo, en TDD o al hacer un cambio de código, ejecutar una prueba unitaria puede ejercer el código de una manera que hace que un contrato falle; cuando esto suceda la prueba debería fallar y usted necesita poder encontrar el contrato que falló de manera rápida y fácil, por lo que puede corregir el código.

Así que de alguna manera se desea capturar una contractexception aunque sólo sea para luego hacer un Asser.Fail ("requisito de contrato no cumplido")

Esto puede ser más lo que está después How to Log error while using Code Contracts