Testing hello world function in python with doctests
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.