pytest-grader
A pytest plugin for testing and scoring programming assignments.
Features
- 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. - A doctest that raises an exception should give
ERRORas its entire expected output, which matches any raised exception (and fails if none is raised). - A doctest statement that displays nothing (e.g.
lst.append(2)) may giveNOTHINGas its expected output, so that unlocking still asks about it. - When unlocking, sentinel answers (
FUNCTION,ERROR,NOTHING) may be typed in any case. - Unlocked outputs are saved in
.unlocked.json(see--unlock-file) so that tests stay unlocked across pytest runs.
- Lock doctests using the
- Test Isolation
- Modules listed under
reload_modulesingrader.jsonare 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
- Test Timeouts
- Each test (including each doctest) is limited to 10 seconds, so an infinite loop fails that test with a clear message instead of hanging the run. The remaining tests still run and are scored.
- Adjust the limit with
--timeout SECONDS;--timeout 0disables it. The timeout is also disabled under--pdb. - Code blocked outside the Python interpreter (e.g. waiting on
input()or a hung C call) cannot be interrupted; pure-Python loops always time out.
Usage
Include a conftest.py file in the distribution of your assignment that contains pytest_plugins = ["pytest_grader"].
Optionally describe the assignment in a grader.json file next to it:
{
"reload_modules": ["hog"]
}
reload_modules lists modules reloaded before each test for isolation.
See the examples directory for more usage info.
License
Updating versions
- Change version in
pyproject.toml uv builduv publishIf your pypi credentials are in~/.pypirc, then instead runuvx uv-publish.
Metadata
Release files for pytest-grader 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_grader-0.3.0.tar.gz | 17.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_grader-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.9 kB
Release files / pytest_grader-0.3.0.tar.gz
| Download URL | pytest_grader-0.3.0.tar.gz |
|---|---|
| Size | 17.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4efc714487f3e53a4db91a5012b195db652a40881f403577c1f1b6f82681c50e
|
|
BLAKE2b-256 checksum How to use checksums |
90d80b9de61b5d273fb5d9ef40dd08de241bcfa2415f0e12ef6bc1e5f163b8b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.13
|
Release files / pytest_grader-0.3.0-py3-none-any.whl
| Download URL | pytest_grader-0.3.0-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bcbb5632019dca149a9b13f06b46874ff4154552c39ac8b58523d826555827dd
|
|
BLAKE2b-256 checksum How to use checksums |
077b960ed15f90e3df4d9ff4c322c90e70912d0a04ad7162aac7536fff841834
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.13
|