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)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-25 08:16 pm (UTC)(link)
Mock тестирование - не просто передает параметры в тестируемую функцию, но и делает дополнительные операции (обычно устанавливает значения некоторых properties у mock объекта), верно?

Аналоги этих дополнительных операций -- выполняются и при регулярном выполнении production code, верно?

Так вот эти аналоги (части production code) -- не покрыты mock тестами.
То есть покрытие неполное.

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-26 08:10 pm (UTC)(link)
Я не вполне согласен.

Представьте, что в код, который исполняет new DateTime(), передаёся какой-нибудь DateTimeCreator с методом newDateTime(), и все вызовы new DateTime() меняются на вызовы newDateTime().

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

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-26 08:15 pm (UTC)(link)
У вас получилось хорошее описание примера использования mock.

> в production мы передаём одну имплементацию DateTimeCreator,

Так вот эта "production" имплементация -- и не тестируется.
И процесс передачи этой "production" имплементации -- тоже не тестируется.

Это и делает тестовое покрытие с помощью mocks - неполным.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-26 08:38 pm (UTC)(link)
What do you mean?
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-26 08:59 pm (UTC)(link)
Если ты разобрался, то почему ты не можешь указать на мою ошибку?

А если ты не разобрался, то откуда ты знаешь, что это ахинея (а не твое упущение)?
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

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

Зачем ты это сделал?
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-26 11:11 pm (UTC)(link)
> Зачем я комментирую ахинею, что ты несешь?

Нет.

Зачем ты высказал утверждение, не относящееся к вопросу, который я задал?

> Чисто из зрительного зала.

Ты имеешь ввиду, что прикольно иногда покричать какие-нибудь глупости из зрительного зала?

> Для взаимопонимания нужно понимание,

Да.

> а у тебя полный швах с этим делом.

Из каких признаков ты сделал такой вывод?

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-27 08:09 pm (UTC)(link)
DateTimeCreator можно тоже покрыть тестами.
Процесс его передачи, наверное, тоже.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-27 11:39 pm (UTC)(link)
> DateTimeCreator можно тоже покрыть тестами.

Если можно покрыть тестами DateTimeCreator, то зачем нужен Mock, подменяющий DateTimeCreator?

> Процесс его передачи, наверное, тоже.

Можно. В полноценном integration тесте, который не использует Mock.

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-28 08:01 pm (UTC)(link)
Если можно покрыть тестами DateTimeCreator, то зачем нужен Mock, подменяющий DateTimeCreator?

Чтобы можно было протестировать наш сервис для разных DateTime.

Можно. В полноценном integration тесте, который не использует Mock.

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

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-29 12:50 am (UTC)(link)
>> Если можно покрыть тестами DateTimeCreator, то зачем нужен Mock, подменяющий DateTimeCreator?

> Чтобы можно было протестировать наш сервис для разных DateTime.

Вы имеете ввиду, что покрыть тестами DateTimeCreator можно, но не для всех значений?
И что Mocks - позволяют тщательно протестировать остальную часть сервиса (а DateTimeCreator будет протестирован лишь для некоторых значений)?

> И в тесте, который использует мок тоже, потому что процессы передачи настоящего "DateTimeCreator" и его мока -- одинаковые.

Нет.
Mock не дает полноценного тестирования в данном случае.
"Передача DateTimeCreator" - состоит из двух частей:
Часть №1: Посылка DateTimeCreator.
Часть №2: Получение DateTimeCreator.

Часть №2 - одна и та же и в тесте с моками и в production коде. Поэтому тестирование покрывает production код.

Но, увы, Часть №1 - разная в коде тестов с моками и в production коде. Поэтому тестирование с моками не покрывает эту Часть №1 ("Посылка DateTimeCreator").

Эту проблему (с отсутствием покрытия "посылки DateTimeCreator" можно продемонстрировать следующим образом:
1) Написать production код.
2) Написать mock test (который successfully passes).
3) Модифицировать ту часть production кода, которая передает DateTimeCreator (чтобы она передавала неправильную функцию).
Mock test, при этом, увы, будет продолжать демонстрировать success (fake success).

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-29 08:32 pm (UTC)(link)
Ага, теперь я, кажется, понял.
Да, при тестировании с моком одна часть рабочего кода не покрывается.
Но её вроде можно покрыть, добавив тест с настоящим DateTimeCreator.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-29 09:51 pm (UTC)(link)
Если тест должен явным образом добавлять работу с настоящим DateTimeCreator, то полного покрытия не получится.

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

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-30 05:11 pm (UTC)(link)
Не могу согласиться. Сервис может включать настоящий DateTimeCreator по умолчанию.
И мы можем протестировать его в таком виде.
А для тестов, которые требуют DateTimeCreator mock, мы втыкаем этот mock в наш сервис вместо настоящего DateTimeCreator-а.
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-30 06:12 pm (UTC)(link)
> Сервис может включать настоящий DateTimeCreator по умолчанию.
> И мы можем протестировать его в таком виде.

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

Похоже, разница между нашими утверждениями лишь в том, что вы называете "моком" лишь изменяемую часть, а я называю "моком" весь класс, который включает в себя изменяемую часть.

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-31 09:09 am (UTC)(link)
Похоже, разница между нашими утверждениями лишь в том, что вы называете "моком" лишь изменяемую часть, а я называю "моком" весь класс, который включает в себя изменяемую часть.

Да, похоже на то. А как правильно ?
dennisgorelik: 2020-06-13 in my home office (Default)

Re: Is full service test coverage possible with mocks?

[personal profile] dennisgorelik 2020-08-30 06:58 pm (UTC)(link)
> Сервис может включать настоящий DateTimeCreator по умолчанию.
> И мы можем протестировать его в таком виде.

Обратите внимание, что обратное - тоже верно: если сервис не включает в себя настоящий DateTimeCreator по умолчанию, то полный test coverage такого кода - невозможен.

Что приводит нас к "best practice" рекомендации о том, как имплементировать моки:
Для того, чтобы повысить test coverage, имплементация мока для рабочего кода - должна быть включена по умолчанию в сервис (чтобы рабочий код, вызывающий этот сервис, не должен был заморачиваться explicit инициализацией mock).

Это, пожалуй, основной вывод из нашей с вами дискуссии о моках.

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-31 09:10 am (UTC)(link)
Это, пожалуй, основной вывод из нашей с вами дискуссии о моках.

Да, можно сделать такой вывод.

Re: Is full service test coverage possible with mocks?

[personal profile] mikkim08 2020-08-30 05:13 pm (UTC)(link)
Да вроде нет, пока держусь.