Я говорю о крупномасштабной системе со многими серверами и недетерминированным вводом большой емкости. Когда я говорю «недетерминированный», я имею в виду сообщения, которые отправляются, и вы ловите то, что можете, и делаете все, что в ваших силах. Есть много типов сообщений, поэтому ввод может быть очень сложным. Я не могу себе представить, как писать код для такого количества сценариев, и простой генератор неслучайных (детерминированных) сообщений недостаточно хорош.
Вот почему я хочу иметь рандомизированный модульный тест или тест сервера, который в случае сбоя мог бы написать журнал.
И я предпочитаю unittest вместо случайного инжектора, потому что я хочу, чтобы он запускался как часть автоматических тестов ночной сборки.
Есть ли недостатки?
Недостатки
Во-первых, это делает тест более запутанным и немного более трудным для отладки, поскольку вы не можете напрямую видеть все вводимые значения (хотя всегда есть возможность генерировать тестовые примеры в виде кода или данных). Если вы используете какую-то полусложную логику для генерации случайных тестовых данных, то есть вероятность, что в этом коде есть ошибка. Ошибки в тестовом коде могут быть неприятны, особенно если разработчики сразу предполагают, что ошибка - это производственный код.
Во-вторых, часто невозможно точно определить ожидаемый ответ. Если вы знаете ответ на основе входных данных, то велика вероятность, что вы просто копируете тестируемую логику (подумайте об этом - если входные данные случайны, откуда вы знаете ожидаемый выход?). В результате вам, возможно, придется обменять очень специфические утверждения (значение должно быть x) на более общие утверждения, проверяющие вменяемость (значение должно быть между y и z).
В-третьих, если нет широкого диапазона входов и выходов, вы часто можете покрыть тот же диапазон, используя хорошо подобранные значения в стандартных модульных тестах с меньшей сложностью. Например, выберите числа -max, (-max + 1), -2, -1, 0, 1, 2, max-1, max. (или любое другое, интересное для алгоритма).
Положительные стороны
При хорошем выполнении с правильной целью эти тесты могут обеспечить очень ценное дополнительное тестирование. Я видел довольно много кусков кода, которые, когда на них обрушивались случайно сгенерированные тестовые входы, ломались из-за непредвиденных краевых случаев. Иногда я добавляю дополнительный проход интеграционного тестирования, который генерирует огромное количество тестовых случаев.
Дополнительные приемы
Если один из ваших случайных тестов провалился, выделите "интересное" значение и переведите его в отдельный модульный тест, чтобы гарантировать, что вы сможете исправить ошибку и она никогда не регрессирует до проверки.
Они случайны.
(Ваш тест может случайно сработать, даже если ваш код сломан.)
Кроме того, вы не сможете воспроизводить тесты много раз. Юнит-тест должен выполняться точно так же с заданными параметрами.
Намного лучше иметь модульные тесты, которые на 100% воспроизводятся и включают все крайние случаи. Например, нулевой тест, отрицательные, положительные, слишком большие числа, слишком маленькие числа и т. Д. Если вы хотите включить тесты со случайными значениями в дополнение ко всем крайним случаям и нормальным случаям, это будет нормально. Однако я не уверен, что вы получите много пользы от потраченного времени. Наличие всех нормальных случаев и крайних случаев должно справиться со всем. Остальное - «подливка».
Результаты не повторяются, и, в зависимости от ваших тестов, вы можете не знать конкретных условий, которые вызвали сбой кода (что затрудняет отладку).
Как предположили другие, это делает ваш тест ненадежным, поскольку вы не знаете, что происходит внутри него. Это означает, что он может работать в одних случаях и не работать в других.
Если у вас уже есть представление о диапазоне значений, которые вы хотите проверить, то вам следует либо (1) создать отдельный тест для каждого значения в диапазоне, либо (2) перебрать весь набор значений и сделать утверждение на каждой итерации. Быстрый и довольно глупый пример...
for($i = 0; $i < 10; $i++)
$this->assertEquals($i + 1, Math::addOne($i));
Можно сделать нечто подобное с кодировками символов. Например, перебрать набор символов ASCII и проверить все эти сумасшедшие символы на одной из ваших функций работы с текстом.
Вам нужно запомнить, какие случайные числа вы генерировали при проверке.
Пример.
Username= "username".rand();
Save_in_DB("user",Username); // To save it in DB
Verify_if_Saved("user",Username);