Я за случайные тесты и пишу их. Однако вопрос о том, подходят ли они в конкретной среде сборки и в какие наборы тестов они должны быть включены, является более нюансированным вопросом.
Запуск локально (например, в одночасье на вашем устройстве разработки) рандомизированные тесты обнаружили ошибки как очевидные, так и неясные. Непонятные из них достаточно загадочны, так что я думаю, что случайное тестирование действительно было единственным реалистичным, чтобы избавиться от них. В качестве теста я взял одну трудно обнаруживаемую ошибку, обнаруженную в ходе рандомизированного тестирования, и попросил полдюжины разработчиков взломать функцию (около десятка строк кода), где она произошла. Никто не смог его обнаружить.
Многие из ваших аргументов против рандомизированных данных являются разновидностями "теста не воспроизводится". Однако хорошо написанный рандомизированный тест захватит начальное число, использованное для запуска рандомизированного начального значения, и выдаст его при неудаче. В дополнение к тому, что вы можете повторить тест вручную, это позволяет вам тривиально создать новый тест, который тестирует конкретную проблему, жестко закодировав начальное значение этого теста. Конечно, было бы лучше написать вручную явный тест, охватывающий этот случай, но лень имеет свои достоинства, и это даже позволяет вам автоматически генерировать новые тестовые случаи из неудачного начального числа.
Единственное, о чем вы не можете спорить, это то, что это ломает системы сборки. Большинство тестов сборки и непрерывной интеграции предполагают, что тесты будут выполнять одно и то же каждый раз. Таким образом, случайный провал теста создаст хаос, случайный провал и будет указывать пальцем на безвредные изменения.
Решение, таким образом, состоит в том, чтобы по-прежнему запускать рандомизированные тесты как часть тестов сборки и CI, но запускать его с фиксированным начальным числом для фиксированного числа итераций . Следовательно, тест всегда делает одно и то же, но все же исследует кучу входного пространства (если вы запускаете его для нескольких итераций).
Локально, например, при изменении соответствующего класса вы можете запускать его для дополнительных итераций или с другими начальными значениями. Если рандомизированное тестирование становится все более популярным, вы можете даже представить конкретный набор тестов, которые, как известно, являются случайными, которые могут запускаться с различными начальными значениями (следовательно, с увеличением охвата с течением времени), и где сбои не означают одно и то же как детерминированные системы CI (т. е. прогоны не связаны 1: 1 с изменениями кода, поэтому вы не указываете на конкретное изменение в случае неудачи).
Многое можно сказать о рандомизированных тестах, особенно хорошо написанных, поэтому не спешите их отклонять!