2010-09-28 3 views
18

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

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

Я не очень доволен этим, но я не вижу выхода. Допустимо ли тестировать методы с частично случайным поведением?

+0

Возможный дубликат [Тестирование метода, который может иметь случайное поведение] (https://stackoverflow.com/questions/88007/unit-testing-a-method-that-can-have-random-behaviour) –

ответ

23

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

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

+0

So это означает, что вы предлагаете мне поставить свою игру генератором случайных чисел, из которых я могу создать макетную реализацию? – forceal

+0

@forceal: Да, это так. –

+0

Hm. Но генератор случайных чисел будет использоваться для нескольких вещей, поэтому было бы очень сложно подделать его. Например, он также используется для цвета игрока (что не влияет на какой-либо другой аспект игры, поэтому я игнорирую его). Единственный способ, который я вижу, - создать класс генератора, содержащий такие методы, как «getRandomPlayerPosition()» и «getRandomPlayerColor()», тогда я мог бы подделать его. Все будет в порядке? – forceal

5

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

3

Сделать источник случайности входным для теста и настроить его одинаково каждый раз.

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

Я должен проверить все ситуации в одном тестовом случае.

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

1

Есть две разные вещи, чтобы проверить здесь, и вы должны проверить их по отдельности:

  • ли логическая программа работы для всех возможных стартовых позиций? Протестируйте это, положив плеер неслучайным на несколько позиций, пытаясь охватить все «особые случаи».
  • Является ли случайное позиционирование фактически случайным? Протестируйте это, вызывая только логику позиционирования много раз, и делайте какой-то статистический анализ.
0

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

1

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

Единственные ситуации, когда мне приходилось иметь дело с недетерминированным кодом, - это когда задействовано многопоточность. Затем вы зависите от планировщика операционной системы.

В таких случаях я пишу unit-test как цикл, который повторяет тысячи раз тестовый код.

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