┌─ write

Rust-like inline unit tests in Python

While solving Advent of Code, I wanted to quickly write test for a simple, but important for solving the puzzle function. I’m using Python, the obvious choice would be to create new file and write test using unittest, or better pytest. I kept thinking that such simple case there must be a way to keep the tests in the same file.

In Rust there is an option to do that, inline tests use a #[cfg(test)] module that only runs during cargo test.

/// Calculate how far Voyager 1 has traveled since launch
///
/// Launched: September 5, 1977
/// Current speed: ~17 km/s (relative to the Sun)
/// This is a simplified calculation assuming constant velocity
fn voyager_distance_from_earth(years_since_launch: f64) -> f64 {
    let speed_km_per_sec = 17.0;
    let seconds_per_year = 365.25 * 24.0 * 3600.0;
    speed_km_per_sec * seconds_per_year * years_since_launch
}

#[cfg(test)]
mod voyager_tests {
    use super::*;

    #[test]
    fn test_voyager_after_48_years() {
        let distance_km = voyager_distance_from_earth(48.0);
        let distance_au = distance_km / 149_600_000.0;
        // At 17 km/s for 48 years = approximately 172.3 AU
        assert!((distance_au - 172.3).abs() < 1.0);
        println!("After 48 years: {:.1} AU from Earth", distance_au);
    }
}

I learned that Python’s doctest module can be used to replicate similar functionality. It’s included in standard library and does not affect the runtime.

def get_golden_record_greeting(language_code: str) -> str:
    """
    Get the greeting from Voyager's Golden Record for a given language.

    >>> get_golden_record_greeting("en")
    'Hello from the children of planet Earth'
    >>> get_golden_record_greeting("pl")
    'Witajcie, istoty z zaświatów'
    >>> get_golden_record_greeting('')
    Traceback (most recent call last):
    ValueError: Language code '' is invalid
    >>> get_golden_record_greeting('da')
    Traceback (most recent call last):
    ValueError: Language code 'da' not supported

    """
    greetings = {
        "en": "Hello from the children of planet Earth",
        "pl": "Witajcie, istoty z zaświatów",
        "es": "Hola y saludos a todos",
        "zh": "祝你好运, 祝你健康",
        # ... there are in total 55 Languages
    }

    if not language_code:
        raise ValueError(f"Language code '{language_code}' is invalid")

    if language_code not in greetings:
        raise ValueError(f"Language code '{language_code}' not supported")

    return greetings[language_code]

For the example above when running python3 -m doctest voyager.py -v I get this output:

Trying:
    get_golden_record_greeting("en")
Expecting:
    'Hello from the children of planet Earth'
ok
Trying:
    get_golden_record_greeting("pl")
Expecting:
    'Witajcie, istoty z zaświatów'
ok
Trying:
    get_golden_record_greeting('')
Expecting:
    Traceback (most recent call last):
    ValueError: Language code '' is invalid
ok
Trying:
    get_golden_record_greeting('da')
Expecting:
    Traceback (most recent call last):
    ValueError: Language code 'da' not supported
ok
1 item had no tests:
    voyager
1 item passed all tests:
   4 tests in voyager.get_golden_record_greeting
4 tests in 2 items.
4 passed.
Test passed.

After bit of testing here are some things I found about the doctest module:

  • works with non standard types, dataclasses, exceptions and multiple assertions
  • pytest can run it with pytest --doctest-modules command, so it can be integrated into test suite
  • all example share the same state

and since it matches output exactly the test will fail on:

  • function printing some additional information to the console
  • non deterministic output (eg. floats)
  • whitespace missmatch

For larger projects I still prefer writing unit tests in separate files, as this approach is more recognized by other developers. Standard testing frameworks also provide more features (setup, teardown, specialized asserts, etc.). However, I might use doctest when I need to test small, self-contained function and have pytest to run it as part of the suite. Maybe doctest deserves more popularity in the Python ecosystem, it’s built into the standard library and very easy to use.

If you are wondering why the examples are space and Voyager-related is that in time of writing this article December 2025 it is the most distant human-made object from Earth.