He estado tratando de resolver este problema: Cómo crear una prueba unitaria que pruebe si una función aborta porque falla un Debug.Assert (de System.Diagnostics
), marcándolo como pasó cuando hace esto y como fallido si no lo hace.Cómo garantizar una depuración.Asegure los incendios correctamente usando NUnit
Sé NUnit
tiene la característica [ExpectedException(typeof(ArgumentException))]
, pero parece que no puedo encontrar qué tipo de excepción es del sitio web de MSDN. La intuición diría que podría ser algo así como una AssertionException, y esa existe ... pero es parte del marco NUnit. Supongo que esa es la excepción de NUnit assert throw around. Puede ser que sea capaz de simplemente nuke mediante el uso de:
[ExpectedException(typeof(Exception))]
Pero esto da lugar al problema de que las ventanas estándar ventana de depuración muestra. En mi búsqueda, encontré formas de eliminar esta ventana para que no apareciera, pero parece como llevar una cuchilla de carnicero a la mesa de cirugía donde normalmente usas un bisturí. Porque quiero poder ver esta ventana cuando sucede algo inesperado, cuando ejecuto mi programa.
supongo que es la solución de la sustitución del método Debug.Assert
con el NUnit
contraparte (todavía estoy al principio de mi proyecto, por lo que no es una demasiado grande de una refactorización), pero supongo que muchos programadores se pega con Debug.Assert
funcionalidad como es estándar en .NET.
Como tal, me gustaría saber cómo 'afirmar' Debug.Assertion
fallas, sin tener que 'asesinar' la pantalla de depuración de Windows de mi proyecto?
Para tener un ejemplo concreto de un contrato en mi código, hay un ejemplo a continuación. Para aquellos que pueda parecer familiar, es la tabla To-Wound del Warhammer 40K tabletop wargame escrito como una función.
static public int assaultToHit(int _attacker_WeaponSkill,
int _defender_WeaponSkill)
{
//Preconditions
Debug.Assert(_attacker_WeaponSkill >= 1 && _attacker_WeaponSkill <= 10,
"Weapon Skill stat must be in range [1,10]");
Debug.Assert(_defender_WeaponSkill >= 1 && _defender_WeaponSkill <= 10,
"Weapon Skill stat must be in range [1,10]");
int target;
if (_attacker_WeaponSkill > _defender_WeaponSkill)
{
target=3;
}
else if (_defender_WeaponSkill >= (_attacker_WeaponSkill + _attacker_WeaponSkill + 1))
{
target=5;
}
else
{
target=4;
}
//postconditions
Debug.Assert(target >= 3 && target <= 5,
"To hit target for assault must be in range [3,5]");
return target;
}
La función de poner a prueba las condiciones previas estaría en la línea de algo como esto:
[TestCase(-1,2)]
[TestCase(1, -2)]
[TestCase(-1, -2)]
[TestCase(11, 2)]
[TestCase(1, 20)]
[TestCase(11, 20)]
[ExpectedException(typeof(Exception))]
public void testContract_AssaultToHit(int _attacker_weaponskill,
int _defender_weaponskill)
{
Warhammer40kRules.assaultToHit(_attacker_weaponskill,
_defender_weaponskill);
}
Eso no es una solución, es lo que deberías estar haciendo. Debug.Asert solo se activa al compilar con depuración activada. Es una herramienta de investigación opcional. Absolutamente nada en su código liberado debe confiar en él para un funcionamiento normal, por lo que no tiene sentido realizar una prueba unitaria de ello. –
@TonyHopkinson Tienes un punto ahí. Pero en la misma medida, uno podría usar Trace.Assert en lugar de usar NUnit Asserts. En ese caso, no necesitaría agregar NUnit framework .dll junto con el resto de su código, ¿verdad? En ese caso, la pregunta seguiría siendo la misma, creo: ¿cómo se puede probar que el Trace.Assert/Debug.Asertó el disparo correctamente usando NUnit? – Xilconic
Nunca pensé en eso para ser honesto. Un Assert es un Assert, no trataría de probarlo más de lo que lo haría con writelines, alertas y MessageBoxes mientras trataba de descubrir por qué mi código no estaba haciendo lo que pensé que debería hacer. Una especie de quien mira la pregunta de los perros guardianes, ¿no es así? Interesante pregunta, pero no veo mucho uso para la respuesta ... –