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]