Поблочное тестирование с функциями, которые возвращают случайные результаты

  1. Новые файлы создаются только одним разработчиком в ветке «main-develop».
  2. Нажимаем новые файлы на «main-develop»
  3. Эти файлы реализуются посредством другие разработчики после pull
69
задан 2 revs, 2 users 100% 25 November 2008 в 01:26
поделиться

10 ответов

В дополнение к тестированию, что функция возвращает дату в желаемом диапазоне, Вы хотите удостовериться, что результат хорошо распределяется. Тест, который Вы описываете, передал бы функцию, которая просто возвратила дату, которую Вы представили!

Так в дополнение к вызыванию функции многократно и тестированию, что результат остается в желаемом диапазоне, я также попытался бы оценить распределение, возможно, путем помещения результатов в блоки и проверки, что блоки имеют примерно равные количества результатов после того, как Вы сделаны. Вам, возможно, понадобятся больше чем 100 вызовов для получения стабильных результатов, но это не походит на дорогое (мудрое время выполнения) функция, таким образом, можно легко выполнить его для нескольких повторений K.

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

33
ответ дан 2 revs, 2 users 89% 7 November 2019 в 09:51
поделиться

Дразните или обманите генератор случайных чисел

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

public interface IRandomGenerator
{
    double Generate(double max);
}

public class SomethingThatUsesRandom
{
    private readonly IRandomGenerator _generator;

    private class DefaultRandom : IRandomGenerator
    {
        public double Generate(double max)
        {
            return (new Random()).Next(max);
        }
    }

    public SomethingThatUsesRandom(IRandomGenerator generator)
    {
        _generator = generator;
    }

    public SomethingThatUsesRandom() : this(new DefaultRandom())
    {}

    public double MethodThatUsesRandom()
    {
        return _generator.Generate(40.0);
    }
}

В Вашем тесте, просто фальсифицируйте или дразните IRandomGenerator для возврата чего-то консервированного.

54
ответ дан Brian Genisio 7 November 2019 в 09:51
поделиться

Я думаю, что существует три различных аспекта этой проблемы, которую Вы тестируете.

первый: действительно ли мой алгоритм является правильным? Таким образом, учитывая правильно функционирующий генератор случайных чисел, это произведет даты, которые случайным образом распределяются через диапазон?

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

третий: моя реализация работы алгоритма? Таким образом, учитывая известный список псевдослучайных исходных данных, это производит ожидаемый список псевдослучайных дат?

первые две вещи не что-то, что я встроил бы в комплект поблочного тестирования. Они - что-то, что я подтвердил бы при разработке системы. Я, вероятно, сделал бы это путем записи тестовой обвязки, которая генерировала огромное количество дат и выполнила тест хи-квадрата, как daniel.rikowski предложенный. Я также удостоверился бы, что эта тестовая обвязка не завершалась, пока она не обработала оба из пограничных случаев (предполагающий, что мой диапазон случайных чисел является достаточно маленьким, что мне может сойти с рук это). И я зарегистрировал бы это, так, чтобы любой, приход и попытка улучшить алгоритм будут знать, что это - повреждающееся изменение.

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

9
ответ дан Robert Rossney 7 November 2019 в 09:51
поделиться

Вы не должны управлять системой для создания результатов детерминированными. Вы находитесь на правильном подходе: решите то, что важно относительно вывода функции и теста для этого. В этом случае важно, чтобы результат был в диапазоне 40 дней, и Вы тестируете на это. Также важно, чтобы это не всегда возвратило тот же результат, таким образом протестировало на это также. Если Вы хотите быть более необычными, можно протестировать это, результаты проходят некоторый тест случайности..

8
ответ дан Ned Batchelder 7 November 2019 в 09:51
поделиться

Если Вы хотите проверить качество случайных чисел (с точки зрения независимости) существует несколько способов сделать это. Один хороший путь Критерий хи-квадрат .

4
ответ дан Daniel Rikowski 7 November 2019 в 09:51
поделиться

В зависимости от того, как Ваша функция создает случайную дату, можно также хотеть проверить на недопустимые даты: невозможные високосные годы или 31-й день 30-дневного месяца.

2
ответ дан mseery 7 November 2019 в 09:51
поделиться

Normaly я использую точно Ваш предложенный подход: Управляйте Случайным генератором. Инициализируйте его для теста с семенем по умолчанию (или замените его прокси, возвратив числа, которые соответствуют моим тестовым сценариям), таким образом, у меня есть детерминированное/тестируемое поведение.

5
ответ дан flolo 7 November 2019 в 09:51
поделиться

Методы, которые не демонстрируют детерминированного поведения , не могут быть должным образом модульно протестированы, так как результаты будут отличаться от одного выполнения к другому. Один из способов обойти это - заполнить генератор случайных чисел фиксированным значением для модульного теста. Вы также можете извлечь случайность класса генерации даты (и, таким образом, применив Принцип единой ответственности ) и ввести известные значения для модульных тестов.

2
ответ дан 24 November 2019 в 13:50
поделиться

Конечно, использование фиксированного генератора случайных номеров семян будет работать просто хорошо, но даже тогда вы просто пытаетесь проверить для того, что вы не можете предсказать. Который в порядке. Это эквивалентно иметь кучу фиксированных тестов. Тем не менее, помните - тестируйте то, что важно, но не пытайся проверить все. Я верю, что случайные тесты - это способ попытаться проверить все, и это не эффективно (или быстро). Вы могли бы потенциально придеться запустить большие многие рандомизированные тесты, прежде чем ударить ошибку.

Что я пытаюсь вот вот то, что вы должны просто написать тест на каждую ошибку, которую вы найдете в вашей системе. Вы проверяете краевые чехлы, чтобы убедиться, что ваша функция работает даже в экстремальных условиях, но на самом деле это лучшее, что вы можете сделать, не тратя слишком много времени, либо заставляя устройства медленно проводить, либо просто теряющие процессорные циклы.

2
ответ дан 24 November 2019 в 13:50
поделиться

FSM никогда не следует считать плохими. Они слишком полезны, но люди, которые не привыкли к ним, часто считают их обременительными.

Существует множество способов реализации одного с OOP. Одни уродливее других. Ваши низкоуровневые ребята будут использовать операторы switch, таблицы переходов или даже «перейти».

Если вы ищете более чистый способ сделать это, я бы рекомендовал библиотеку диаграмм состояний Boost , которая построена только для реализации диаграмм состояний UML в C++. Он использует современные шаблонные методы, чтобы сделать вещи более читаемыми. Также очень хорошо выступает.

-121--3440526-

Языки домена. Смотрите, например, эту книгу .

-121--3677750-

Я бы рекомендовал переопределить случайную функцию. Я выполняю модульное тестирование в PHP, поэтому я пишу этот код:

// If we are unit testing, then...
if (defined('UNIT_TESTING') && UNIT_TESTING)
{
   // ...make our my_rand() function deterministic to aid testing.
   function my_rand($min, $max)
   {
      return $GLOBALS['random_table'][$min][$max];
   }
}
else
{
   // ...else make our my_rand() function truly random.
   function my_rand($min = 0, $max = PHP_INT_MAX)
   {
      if ($max === PHP_INT_MAX)
      {
         $max = getrandmax();
      }
      return rand($min, $max);
   }
}

Затем я устанавливаю random_table, как я требую его для каждого теста.

Проверка истинной случайности случайной функции вообще является отдельным тестом. Я бы избегал тестирования случайности в единичных тестах и вместо этого делал бы отдельные тесты и гуглировал истинную случайность случайной функции на языке программирования, который вы используете. Недетерминированные тесты (если таковые вообще имеются) следует исключить из единичных испытаний. Может быть, есть отдельный номер люкс для этих тестов, который требует человеческого вклада или гораздо больше времени работы, чтобы минимизировать шансы на сбой, который действительно является пропуском.

1
ответ дан 24 November 2019 в 13:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: