I have a function that prints a somewhat random string to the console, for example:
from random import choice
def hello():
print(f"Hello {choice(('Guido', 'Raymond'))}!")
Please note that my actual function is more complicated than this. The random part is a request to a database that can either succeed or fail. This means that I cannot initialize a seed to have a constant outcome.
What I have tried is to use the ellipsis, but I also need to add an ugly comment for doctest to recognize it.
def hello():
"""
>>> hello() # doctest: +ELLIPSIS
Hello ...!
"""
print(f"Hello {choice(('Guido', 'Raymond'))}!")
Is there a better strategy in this situation?
For example, instead of an ellipsis it would be great if I could test that the answer is one between Hello Guido!
and Hello Raymond!
.
You could use regex: Hello
followed by either Guido
or Raymond
followed by an exclamation point and newline: Hello (Guido|Raymond)!\n
However, capturing the stdout and running the regex is a lot of noise for a doctest. So instead, it'd be better to give an example in the docstring but skip testing it, and use a different test system, like pytest, which has a builtin way to capture stdout. For example:
from random import choice
def hello():
"""
>>> hello() # doctest: +SKIP
Hello Raymond!
"""
print(f"Hello {choice(('Guido', 'Raymond'))}!")
import re
def test_hello(capsys):
hello()
captured = capsys.readouterr()
assert re.fullmatch(r'Hello (Guido|Raymond)!\n', captured.out)