Беручи свій приклад (з невеликим рефакторингом),
assert(a + b, math.add(a, b));
не допомагає:
- зрозуміти, як
math.add
себе поводить,
- знайте, що буде з крайовими справами.
Це майже так, як сказати:
- Якщо ви хочете знати, чим займається метод, перегляньте сотні рядків вихідного коду самостійно (адже так, вони
math.add
можуть містити сотні LOC; див. Нижче).
- Я не переймаюся, чи правильно працює метод. Це нормально, якщо очікувані та фактичні значення відрізняються від тих, що я насправді очікував .
Це також означає, що вам не потрібно додавати тести, наприклад:
assert(3, math.add(1, 2));
assert(4, math.add(2, 2));
Вони нічим не допомагають, або, принаймні, коли ви зробили перше твердження, друге не приносить нічого корисного.
Натомість про що:
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.");
Це зрозуміло і чортово корисно як для вас, так і для людини, яка підтримуватиме вихідний код пізніше. Уявіть, що ця людина робить незначну зміну для math.add
спрощення коду та оптимізації продуктивності, і бачить результат тесту на зразок:
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
ця людина відразу зрозуміє, що нещодавно змінений метод залежить від порядку аргументів: якщо перший аргумент є цілим числом, а другий - довгим числовим, результат буде цілим числом, тоді як очікувалося довге числове число.
Таким же чином, отримання фактичного значення 4.141592
при першому твердженні само собою зрозуміле: ви знаєте, що метод повинен мати справу з великою точністю , але насправді він не вдається.
З тієї самої причини два наступні твердження можуть мати сенс у деяких мовах:
// 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));
А як же:
assert(numeric.Infinity, math.add(numeric.Infinity, 1));
Пояснення теж: ви хочете, щоб ваш метод міг правильно поводитися з нескінченністю. Вихід за межі нескінченності або викидання виключення - це не очікувана поведінка.
А може, залежно від вашої мови, це матиме більше сенсу?
/**
* 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?
Ніхто насправді не знає :)