Prenant votre exemple (avec un peu de refactoring),
assert(a + b, math.add(a, b));
n'aide pas à:
- comprendre comment
math.add
se comporte en interne,
- savoir ce qui se passera avec les cas marginaux.
Cela revient à dire:
- Si vous voulez savoir ce que fait la méthode, allez voir les centaines de lignes de code source vous-même (car, oui,
math.add
peut contenir des centaines de LOC; voir ci-dessous).
- Je ne me soucie pas de savoir si la méthode fonctionne correctement. C'est correct si les valeurs attendues et réelles sont différentes de ce que j'attendais vraiment .
Cela signifie également que vous n'avez pas besoin d'ajouter des tests comme:
assert(3, math.add(1, 2));
assert(4, math.add(2, 2));
Ils n'aident pas non plus, ou du moins, une fois que vous avez fait la première affirmation, la seconde n'apporte rien d'utile.
Au lieu de cela, qu'en est-il:
const numeric Pi = 3.1415926535897932384626433832795;
const numeric Expected = 4.1415926535897932384626433832795;
assert(Expected, math.add(Pi, 1),
"Adding an integer to a long numeric doesn't give a long numeric result.");
assert(Expected, math.add(1, Pi),
"Adding a long numeric to an integer doesn't give a long numeric result.");
Cela s'explique de lui-même et est extrêmement utile pour vous et pour la personne qui conservera le code source plus tard. Imaginez que cette personne modifie légèrement le math.add
pour simplifier le code et optimiser les performances, et voit le résultat du test comme:
Test TestNumeric() failed on assertion 2, line 5: Adding a long numeric to an
integer doesn't give a long numeric result.
Expected value: 4.1415926535897932384626433832795
Actual value: 4
cette personne comprendra immédiatement que la méthode nouvellement modifiée dépend de l'ordre des arguments: si le premier argument est un entier et le second est un long numérique, le résultat serait un entier, alors qu'un long numérique était attendu.
De la même manière, l'obtention de la valeur réelle de 4.141592
lors de la première assertion est explicite: vous savez que la méthode est censée traiter avec une grande précision , mais en fait, elle échoue.
Pour la même raison, deux affirmations suivantes peuvent avoir un sens dans certaines langues:
// We don't expect a concatenation. `math` library is not intended for this.
assert(0, math.add("Hello", "World"));
// We expect the method to convert every string as if it was a decimal.
assert(5, math.add("0x2F", 5));
Et qu'en est-il de:
assert(numeric.Infinity, math.add(numeric.Infinity, 1));
Explicite aussi: vous voulez que votre méthode puisse gérer correctement l'infini. Aller au-delà de l'infini ou lever une exception n'est pas un comportement attendu.
Ou peut-être, selon votre langue, cela aura plus de sens?
/**
* Ensures that when adding numbers which exceed the maximum value, the method
* fails with OverflowException, instead of restarting at numeric.Minimum + 1.
*/
TestOverflow()
{
UnitTest.ExpectException(ofType(OverflowException));
numeric result = math.add(numeric.Maximum, 1));
UnitTest.Fail("The tested code succeeded, while an OverflowException was
expected.");
}
How does unit testing work?
Personne ne sait vraiment :)