A pytest plugin for testing and scoring programming assignments.
- Assignment Scoring
- Add point values to test functions using the
@points(n)decorator - Show a score summary when running
pytest --score
- Add point values to test functions using the
- Test Locking as described in Basu et al., Automated Problem Clarification at Scale (abstract, pdf)
- Lock doctests using the
# LOCKcomment before the function. pytest-grader lock [src] [dst]will generate a copy of src with doctests locked.pytest --unlockprovides an interactive interface for unlocking locked doctests.- A doctest whose output is a function should give
FUNCTIONas the expected output, which matches any function value. When unlocking, typeFUNCTIONfor such outputs.
- Lock doctests using the
- Test Isolation
- Modules listed under
reload_modulesingrader.yamlare reloaded before each test, so a test that mutates a module (e.g. by monkeypatching one of its functions) does not affect later tests. - Globals injected by pytest's assertion rewriting (
@py_builtins,@pytest_ar) are removed from doctest namespaces.
- Modules listed under
- Progress Logging
- Snapshots of assignment files, test case results, and unlocking attempts are stored in a
grader.sqlite. - This file is designed to be submitted along with the assignment as a record of how the assignment was completed.
- Snapshots of assignment files, test case results, and unlocking attempts are stored in a
Include a conftest.py file in the distribution of your assignment that contains pytest_plugins = ["pytest_grader"].
Describe the assignment in a grader.yaml file next to it:
included_files: # Files snapshotted into grader.sqlite when tests run
- hog.py
reload_modules: # Modules reloaded before each test for isolation
- hogSee the examples directory for more usage info.
- Change version in
pyproject.toml uv builduv publishIf your pypi credentials are in~/.pypirc, then instead runuvx uv-publish.