Elixir doctest не работает для функции, которая возвращает случайные значения

У меня есть функция в Elixir, которая производит три случайных кортежа RGB в списке.

defmodule Color do



  @doc """
  Create three random r,g,b colors as a list of three tuples

  ## Examples

      iex> colors = Color.pick_color()
      iex> colors
      [{207, 127, 117}, {219, 121, 237}, {109, 101, 206}]

  """
      def pick_color() do
        color = Enum.map((0..2), fn(x)->
          r = Enum.random(0..255)
          g = Enum.random(0..255)
          b = Enum.random(0..255)
          {r, g, b}
        end)
end

Когда я запускаю свои тесты, мои тесты проваливаются. Полученный список кортежей отличается от того, что определено в моем doctest. Как я могу написать doctest для функции, которая возвращает случайное значение?

2 ответа

Решение

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


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

Вот тест, который бы убедился Color.pick_color() создает список из 3 кортежей, используя сопоставление с образцом:

test "pick color" do
    [{_, _, _}, {_, _, _}, {_, _, _}] = Color.pick_color()
end

Вы также можете проверить, если каждое значение между 0 а также 255, так далее.

Вы можете сделать случайные функции детерминированными, установив начальное число :rand Генератор случайных чисел. Это также как Enum.random/1 проверено в эликсире.

Во-первых, открыть iex и установите начальное значение текущего процесса в любое значение:

iex> :rand.seed(:exsplus, {101, 102, 103})

Затем запустите вашу функцию в iex

iex> Color.pick_color()

Теперь просто скопируйте это значение в ваш doctest вместе с :rand.seed вызов. Путем явной установки начального числа вы получите те же значения из функций в :rand модуль и Enum.random/1 использования :rand внутренне.

iex(1)> :rand.seed(:exsplus, {1, 2, 3})
iex(2)> for _ <- 1..10, do: Enum.random(1..10)
[4, 3, 8, 1, 6, 8, 1, 6, 7, 7]
iex(3)> :rand.seed(:exsplus, {1, 2, 3})
iex(4)> for _ <- 1..10, do: Enum.random(1..10)
[4, 3, 8, 1, 6, 8, 1, 6, 7, 7]
iex(5)> :rand.seed(:exsplus, {1, 2, 3})
iex(6)> for _ <- 1..10, do: Enum.random(1..10)
[4, 3, 8, 1, 6, 8, 1, 6, 7, 7]
Другие вопросы по тегам