pico-pytest

A minimalistic re-implementation of pytest core functionality for educational purposes

Moderate Pure Nim score 36/100 · last commit 2025-11-16 · 6 stars · tests present · no docs generated

Summary

Latest Version Unknown
License Unknown
CI Status Failing
Stars 6
Forks 4
Open Issues 0
Last Commit 2025-11-16
Downloads 0
Last Indexed 2026-09-07 06:08

Installation

nimble install pico-pytest
choosenim install pico-pytest
git clone https://gitlab.com/obestwalter/pico-pytest

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
pico-pytest - - - - - - -

README

pico-pytest

If you are looking for the original talk materials from the 2019 talk - they are in the 2019-pycon.de tag.

This developed from a joke a while ago, that the basic functionality of pytest could be implemented in about 50 lines of Python code. I was wrong, it's about 20 lines (by some very stoopid and narrow definition of "basic functionality" .. it's a joke - ok?).

import importlib.util
from pathlib import Path
import sys

def main():
    results = []
    for path in Path.cwd().glob("**/test_*.py"):
        spec = importlib.util.spec_from_file_location(path.stem, path)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        for name in [n for n in dir(module) if n.startswith("test_")]:
            obj = getattr(module, name)
            if callable(obj):
                try:
                    obj()
                    results.append((".", f"{module.__name__}::{name}"))
                except Exception as e:
                    results.append(("F", f"{module.__name__}::{name}"))
    print("=" * 80, "\n", "".join(r[0] for r in results), "\n", "=" * 80, sep="")
    if any(r[0] == "F" for r in results):
        sys.exit(
            f"{[r[0] for r in results].count('F')} tests failed :(\n"
            + "\n".join(r[1] for r in results if r[0] == "F"))

It turns out that approaching a tool or library that way, you can't help but learn more about the tool and the language it is implemented in, so I took this a bit further and asked myself, what you can do with 100 lines and with fewer dependencies (e.g. only relying on a few imports from the standard library to be forced to use more of the underlying language mechanics). This turned into a talk delivered at the pycon.de in 2019.

I recently revisited that talk, when thinking about how meta you can get with talks done in a Jupyter notebook, so I thought I just redo this and go a bit more meta with the materials. This turned into a new talk now, that creates a complete installable command line tool from a Jupyter notebook and also implements test parametrization on top of discoevery, execution, fixture, marking and filtering. The implementation is 99 codes now without the "build framework" to create the tool - the "build framework" fits on a slide though :)

Running the Notebook (not as slides)

You can run the notebok in any jupyter lab or jupyter notebook environment. All you need to make sure is that you have pytest installed in the same environment as that is used for demonstration, comparison and to patch the pico-pytest functions into it (>:O ... I know - I said that the whole thing is based on a joke and it still is one - just more elaborate ;)).

Running this on any OS should work, as long as you have a currently supported Python version installed:

python -m venv .venv
source .venv/bin/activate
pip install jupyterlab pytest
jupyter lab pipy-full.ipynb

Running the talk as slides

This is an old talk and it is based on RISE and Notebook 6.x. This is not maintained or supported anymore, so to not have to redo everything, I hacked something together to make it work for me on Linux using a frankensteinian approach with mamba and pip, including explicitly downgrading a package. This is not supposed to work, but it does :) - this currently works for me and if you want to play with it you can run (with mamba already installed and initialized):

source scripts/bootstrap.sh
source scripts/start-talk.sh pipy-full.ipynb