Skip to main content

Testing hello world function in python with doctests

· 5 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

Sometimes even the simplest programs deserve solid testing-especially when you're working in a team or trying to set strong standards for code quality. In this note, we'll take the most basic example-"Hello, World!"-and build out everything around it to demonstrate how doctests can be used effectively, even for something so trivial. The goal is to build intuition for testing, not just solve a toy problem.


Here’s our base function:

def say_hello(name: str) -> str:
"""
Returns a greeting string with the given name.

>>> say_hello("World")
'Hello, World!'
>>> say_hello("Alice")
'Hello, Alice!'
>>> say_hello("")
'Hello, !'
"""
return f"Hello, {name}!"

So what’s happening here?​

The function say_hello accepts a string name and returns a greeting. The triple-quoted string under the function is a docstring. Inside that docstring, the >>> syntax is used to write doctests. These are inline examples that are not only documentation but also executable tests. Why Use Doctest? Doctest is great for two main reasons:

Documentation and testing in one place: Anyone reading the function sees what inputs are expected and what outputs should be returned. Quick validation: You can validate code behavior without setting up a complex test suite. Running the Doctests To run the doctests, simply save the function in a Python file, say hello.py, and then run it from the terminal like this:

python -m doctest -v hello.py
You’ll see output like:

Trying:
say_hello("World")
Expecting:
'Hello, World!'
ok
Trying:
say_hello("Alice")
Expecting:
'Hello, Alice!'
ok
Trying:
say_hello("")
Expecting:
'Hello, !'
ok
1 items had no tests:
hello
1 items passed all tests:
3 tests in hello.say_hello
3 tests in 2 items.
3 passed and 0 failed.
Test passed.

Notes on Edge Cases​

Even for simple functions, always consider edge cases. In this example:

Empty string: What does say_hello("") return?​

None as input: What if someone passes None instead of a string?

Non-string types: Should we type-check?​

Let’s extend the function with a more defensive programming style:

def say_hello(name: str) -> str:
"""
Returns a greeting string with the given name.

>>> say_hello("World")
'Hello, World!'
>>> say_hello("Alice")
'Hello, Alice!'
>>> say_hello("")
'Hello, !'
>>> say_hello(123) # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
TypeError
"""
if not isinstance(name, str):
raise TypeError("Name must be a string")
return f"Hello, {name}!"
Integration with Editor (VS Code or Gitpod)

If you're working in VS Code or Gitpod, you can run doctests easily by:

Installing the Python extension.
Creating a test script (e.g., hello.py).
Right-clicking and selecting "Run Python File in Terminal" to see results.
Alternatively, using unittest or pytest in tandem for more complex testing.
In Gitpod, you might just run:

python -m doctest -v hello.py
in the terminal after writing the file.

Final Thoughts​

Doctests should not replace unit tests, but they are powerful complements to them. They are especially useful for small utility functions, example-driven APIs, and when you want your documentation to stay honest and live.

If you start with doctests from the beginning-even for "Hello, World!"-you develop a culture of correctness and verification. That’s a win.