c# assert code-contracts

c# - Debug.Assert vs Code Uso del contrato



code-contracts (2)

Estas son cosas diferentes. Una afirmación de depuración solo se ejecuta cuando el código se compila como depuración y, por lo tanto, solo se verifica / afirma bajo depuración. La idea es usar esto para "verificaciones de cordura" para el código que está desarrollando. Los contratos de código se pueden usar en depuración o liberación. Aseguran que las condiciones pre y post de los métodos cumplen con las expectativas del método (cumplir el contrato). También hay un marco de prueba que proporciona una funcionalidad similar, diseñada para verificar el cumplimiento de las pruebas.

Use Debug.Assert cuando desee asegurarse de que ciertas cosas sean las que espera al desarrollar el código (y en posteriores desarrollos de mantenimiento).

Utilice contratos de código cuando desee asegurarse de que las condiciones sean verdaderas tanto en la depuración como en la versión. Los contratos también permiten ciertas formas de análisis estático que pueden ser útiles para verificar que su programa sea "correcto".

Utilice las aserciones del marco de prueba al crear pruebas unitarias.

¿Cuándo debo depurar. Asiento sobre los contratos de código o viceversa? Quiero verificar la precondición para un método y estoy confundido para elegir uno sobre el otro. Tengo pruebas unitarias donde quiero probar escenarios de falla y esperar excepciones.

¿Es una buena práctica usar Debug.Asertar y codificar el contrato en el mismo método? Si es así, ¿cuál sería el orden en el que debería escribirse el código?

Debug.Assert(parameter!= null); Contract.Requires<ArgumentNullException>(parameter != null, "parameter");

o

Contract.Requires<ArgumentNullException>(parameter != null, "parameter"); Debug.Assert(parameter!= null);

¿Hay alguna razón detrás de esto?


Personalmente, no usaría Debug.Assert AND Code Contracts para hacer cumplir las condiciones previas en el código recién escrito. Los contratos de código de IMO sustituyen a Debug.Assert , ya que ofrecen un conjunto más completo de cheques, sin mencionar el beneficio que se puede obtener de la comprobación estática que se puede realizar antes de que el código llegue al tiempo de ejecución . Mantener las comprobaciones de precondición duplicadas tanto en Debug.Assert como en Contracts será engorroso.

Razón fundamental:

  • No es necesario volver a codificar las condiciones previas heredadas que haya codificado en Debug.Assert o throw código: puede conservar el código de verificación de precondición existente y finalizarlo con Contract.EndContractBlock()
  • Puede obtener el mismo comportamiento de ''modo de liberación'' sin marcar cuando System.Diagnostics.Debug se System.Diagnostics.Debug sin /d:DEBUG si construye con comprobación de tiempo de ejecución contratada establecida en None . Ref. 6.2.1 en los documentos
  • Contracts permite que un desarrollador sea más expresivo en el código en cuanto a "por qué" se ha detectado un estado inválido, por ejemplo, fue directamente debido a un parámetro fuera de banda ( Contract.Requires ). De lo contrario, Contract.Assert o Contract.Assume pueden verificar el estado general, y la "corrección garantizada" del estado al dejar un método puede expresarse mediante Contract.Ensures . Y los Invariants expresan que el estado debe mantenerse en todo momento.
  • Y lo mejor de todo es que la comprobación estática puede hacer cumplir estos Contratos a medida que construye su código, de esta forma tiene la oportunidad de recoger el error a través de un tiempo de diseño o una advertencia de tiempo de compilación en lugar de tener que esperar el tiempo de ejecución. Las verificaciones contractuales se pueden agregar a su integración continua para detectar el incumplimiento.

Una advertencia: si va a escribir pruebas unitarias que infringen deliberadamente los contratos, es posible que tenga que tratar con ContractException : Jon Skeet explica esto bien here . Por ejemplo, cablee un controlador Contract.ContractFailed en su configuración de prueba a un controlador que llame a SetHandled y luego arroje una excepción pública que puede capturar y afirmar en su UT.