2013-02-11 5 views
3

У меня есть метод, который возвращает случайное число в диапазоне от 0 до 10.Написание тест JUnit для генератора случайных чисел

public int roll(){ 
    int pinsKnockedDown = (int) (Math.random() * 10); 
    return pinsKnockedDown; 
} 

Как бы я написать тест JUnit для этого? До сих пор я поставил вызов в цикле, так он работает в 1000 раз и не проходит тест, если - число меньше 0 - число больше чем 10

Как я могу проверить, что все числа Арен» т так же, т.е.

Dilbert

+1

Запустите его много раз (миллионов), подсчитайте количество вхождений каждого номера и решите, достаточно ли он для вас случайным образом. См. Например: http://en.wikipedia.org/wiki/Statistical_randomness – assylias

+0

Возможно, вам нужно что-то, что подходит к равномерному распределению. Это не то, что вы можете легко «протестировать» с помощью модульных тестов, вместо того, чтобы было бы легче (и, возможно, более полезно) доказать, что ваш RNG создает единый дистрибутив для диапазона, который вы хотите. – Cubic

+0

Я бы не стал , Это модульное тестирование сошло с ума. Форма кода гарантирует результат. Вам не нужно тестировать библиотечные API или умножать на десять. – EJP

ответ

2

Мой ответ уже был испорчен, мне нужно было вернуть число от 0 до 10, но мой исходный пост только вернул диапазон от 0 до 9! Вот как я узнал об этом ...

Loop 100k раз и убедитесь, что диапазон верен, он должен быть 0-10 (хотя я установил 10 в качестве переменной, используемый).

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

Если самые высокие и самые низкие значения совпадают, то это индикатор того, что кто-то подделал возврат случайного числа.

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

@Test 
public void checkPinsKnockedDownIsWithinRange() { 
    int pins; 
    int lowestPin = 10000; 
    int highestPin = -10000; 

    for (int i = 0; i < 100000; i++) { 
     pins = tester.roll(); 
     if (pins > tester.NUMBER_OF_PINS) { 
      fail("More than 10 pins were knocked down"); 
     } 
     if (pins < 0) { 
      fail("Incorrect value of pins"); 
     } 

     if (highestPin < pins) { 
      highestPin = pins; 
     } 

     if (lowestPin > pins) { 
      lowestPin = pins; 
     } 
    } 

    if (lowestPin == highestPin) { 
     fail("The highest pin count is the same as the lowest pin count. Check the method is returning a random number, and re-run the test."); 
    } 

    if (lowestPin != 0) { 
     fail("The lowest pin is " + lowestPin + " and it should be zero."); 
    } 

    if (highestPin != tester.NUMBER_OF_PINS) { 
     fail("The highest pin is " + highestPin + " and it should be " + tester.NUMBER_OF_PINS + "."); 
    } 

} 
+0

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

2

Randomness tests являются потенциально сложными. например в приведенном выше вы просто хотите убедиться, что вы получаете номера от 1 до 10? Вы хотите обеспечить равномерное распределение и т. Д.? На каком-то этапе я предлагаю вам хотеть доверять Math.random() и просто убедитесь, что вы не испортили лимиты/диапазон, что по сути является тем, что вы делаете.

1

Вы хотите проверить ваш код, а не качество Java поставляется Math.random(). Предположим, что метод Java хорош. Все тесты необходимы, но не достаточные условия для правильности. Поэтому выберите некоторые тесты, которые позволят выявить вероятные ошибки программирования при использовании предоставленного Java метода.

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

Смежные вопросы