Принимая ваш пример (с небольшим рефакторингом),
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?
Никто на самом деле не знает :)