juan_gandhi: (Default)
Juan-Carlos Gandhi ([personal profile] juan_gandhi) wrote2020-08-23 09:18 pm

TWIMC: tests using random and current time

 So, if you think you call a function in your code, and this function returns current time, or a random number... IT'S NOT A FUNCTION. Your code is function of "random number", or "time".

So, if your code is written as something that retrieves this kind of data, to test your code, you should provide that data. Not just today, but try the time, like 10 years from now. As to "random", You provide the randomness. If your code cannot be fixed to behave as a function of those inputs, make your "random stream" or "time stream" not hard-coded, but substitutable. Mockable. And mock it in your tests. MAKE SURE that you don't provide just happy-path data. Provide anything. A sequence of 100 numbers 4 for random. Time that is 10 years from now. Or even 30 yeas from now.

Make sure that your tests don't depend on anything. Because test Must Be Reproducible.

All these things, I know, are obvious to some, and not obvious to others.

If you still have questions, ask. But don't argue. Because what I say is math. Unless you have another math (some people do), or another logic (there's plenty of them), please don't argue.

I'd be glad to see how all this changes if logic is e.g. linear. 

 

dennisgorelik: 2020-06-13 in my home office (Default)

Multiple separate places to modify code

[personal profile] dennisgorelik 2020-08-25 03:36 pm (UTC)(link)
>> Необходимость изменять данные в двух местах - отнимает дополнительное время и создает существенные проблемы.

> В двух местах это в смысле и в имплементации сервиса, и в тестах для него ?

Да.
Не так уж и важно что это за два места. Проблематично, что таких мест - больше одного.

Re: Multiple separate places to modify code

[personal profile] mikkim08 2020-08-25 03:38 pm (UTC)(link)
Мне кажется это естественным. Если меняются требования, то нужно переделывать и тесты, и сам сервис.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Multiple separate places to modify code

[personal profile] dennisgorelik 2020-08-25 03:50 pm (UTC)(link)
> Если меняются требования, то нужно переделывать и тесты, и сам сервис.

Иногда нужно. Но далеко не всегда.
Например, если у нас есть длинный словарь, и новые требования нуждаются в расширении этого словаря -- из этого совсем не следует, что тесты тоже нужно при этом расширять.

Re: Multiple separate places to modify code

[personal profile] mikkim08 2020-08-25 08:12 pm (UTC)(link)
Бывает, конечно, по-разному, и "хрупкие" тесты, которые нужно всё время переделывать, я тоже не люблю, но в целом тот факт, что при изменении требований нужно переделывать и сервис, и тесты, меня не очень заботит.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Multiple separate places to modify code

[personal profile] dennisgorelik 2020-08-25 08:21 pm (UTC)(link)
> что при изменении требований нужно переделывать и сервис, и тесты, меня не очень заботит.

Я согласен, что необходимость менять код в нескольких местах при изменении одного требования -- это далеко не самое страшное, что случается при поддержке кода.
Но, все же, довольно неприятно.
Потому что можно же одно из мест упустить из виду. Тесты, обычно, помогают самодиагностироваться, но не всегда.

Re: Multiple separate places to modify code

[personal profile] mikkim08 2020-08-26 08:02 pm (UTC)(link)
Видимо, тут имеет место компромисс между количеством тестов и накладными расходами на их поддержку. Выбор тут, наверное, зависит от многих разных факторов, в том числе субъективных. Но я могу себе представить ситуации, когда лучше написать побольше тестов несмотря на затраты по их сопровождению чем наоборот.

Потому что можно же одно из мест упустить из виду. Тесты, обычно, помогают самодиагностироваться, но не всегда.

Я не знаю, что конкретно имеется в виду, но тесты, наверное, нужно писать так, чтобы они помогали самодиагностироваться всегда.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Multiple separate places to modify code

[personal profile] dennisgorelik 2020-08-26 08:09 pm (UTC)(link)
> могу себе представить ситуации, когда лучше написать побольше тестов несмотря на затраты по их сопровождению

Да, бывает и так.

> тесты, наверное, нужно писать так, чтобы они помогали самодиагностироваться всегда

Это невозможно.
Тем более, что самодиагностика - это лишь второстепенная цель тестов.
Основная цель тестов - диагностировать production code.

Re: Multiple separate places to modify code

[personal profile] mikkim08 2020-08-26 08:12 pm (UTC)(link)
Возможно, я не понял, что значит самодиагностика и для чего она. Можете привести пример ?
dennisgorelik: 2020-06-13 in my home office (Default)

Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-26 08:20 pm (UTC)(link)
Let's imagine we have production method
~~~
static int Return1() {return 1;}
~~~

If in test we incorrectly write:
-----
Assert.AreEqual(2, Return1())
-----
then this test will complain (fail). That complain will force developer to investigate and find out that test (but not production code) contained error.
So that ability of test to [sometimes] find problems in its own code -- I call "self-diagnostic".

Does it make sense?

Re: Tests self-diagnostic

[personal profile] mikkim08 2020-08-27 08:11 pm (UTC)(link)
Да, такое может быть. Но эти ошибки исправляются в процессе написания этих тестов, так что в релизе их не будет.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-27 11:35 pm (UTC)(link)
> Но эти ошибки исправляются

Вы так пишете, как будто считаете способность тестов к самодиагностике - проблемой.
Способность тестов к самодиагностике - не проблема, а достоинство.
Проблема заключается в том, что тесты могут далеко не все свои ошибки самодиагностировать.
Например в этом случае:
~~~
static int Return1() {return 2;}
~~~

этот тест:
-----
Assert.AreEqual(2, Return1())
-----
Не в состоянии выявить проблему (passes).
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-28 12:19 am (UTC)(link)
Проблема в том, что, с точки зрения бизнес требований, нужно чтобы результат был 1 (это требование отражено в названии метода Return1()).
Но и в имплементации и в тестовом коде - ошибки.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-28 08:48 am (UTC)(link)
> Не отражено.

Отражено.
Я - автор этого метода.
Я знаю, что именно я вложил в имя этого метода, когда назвал его "Return1".


> Первый Возврат, и чо?

"Первый Возврат" - это твоя некорректная интерпретация имени.
Из этого может следовать, что этот метод желательно переименовать (чтобы уменьшить вероятность некорректной интерпретации в будущем).
Но ошибка в тесте от переименования метода не исчезнет, потому что метод, в соответствии с бизнес требованиями - все равно должен возвращать 1.

Re: Tests self-diagnostic

[personal profile] mikkim08 2020-08-28 07:57 pm (UTC)(link)
Возможно, я тогда ошибся. Теперь я понял, что имеется в виду.
К счастью мне такие случаи не встречались на практике, так что я полагаю их вероятность минимальной.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-29 12:52 am (UTC)(link)
Вы имеете ввиду, что вам не встречались тесты, которые successfully pass, а production код, при этом, работает неправильно?

Re: Tests self-diagnostic

[personal profile] mikkim08 2020-08-29 08:33 pm (UTC)(link)
Да, такого типа не встречались.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Tests self-diagnostic

[personal profile] dennisgorelik 2020-08-29 09:52 pm (UTC)(link)
"Такого типа" - это какого?

Re: Tests self-diagnostic

[personal profile] mikkim08 2020-08-30 05:12 pm (UTC)(link)
Чтобы была ошибка в production коде и компенсирующая её ошибка в тесте.

Re: Tests self-diagnostic

[personal profile] sassa_nf 2020-08-29 08:12 am (UTC)(link)
It's a bug in the specification. It happens sometimes. But the tests only test the correspondence between the test and the code, not between the code and the intention.

Say:
fn is_even(x: u32) -> bool {
   is_odd(x + 1)
}

fn is_odd(x: u32) -> bool {
   x != 0 && is_even(x + 1)
}
the bug in the intention is not very easy to see. (And, by the way, is_odd(2) produces 100% code coverage, which says something about that metric).

Re: Tests self-diagnostic

[personal profile] mikkim08 2020-08-29 08:35 pm (UTC)(link)
It's a bug in the specification.

Разве ? По-моему, это больше похоже на "чётное количество ошибок".