Metadata-Version: 2.4
Name: pytest-grader
Version: 0.1.5
Summary: Pytest extension for scoring programming assignments.
License-Expression: MIT
Classifier: Framework :: Pytest
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pytest>=8
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: sqlitedict>=2.1.0
Dynamic: license-file

# 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`
- **Test Locking** as described in Basu et al., *Automated Problem Clarification at Scale* ([abstract](https://dl.acm.org/doi/10.1145/2724660.2724679), [pdf](http://denero.org/content/pubs/las15_basu_unlocking.pdf))
  - Lock doctests using the `# LOCK` comment before the function.
  - `pytest-grader lock [src] [dst]` will generate a copy of src with doctests locked.
  - `pytest --unlock` provides an interactive interface for unlocking locked doctests.
- **Test Isolation**
  - Modules listed under `reload_modules` in `grader.yaml` are 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.
- **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.

## Usage

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:

```yaml
included_files:   # Files snapshotted into grader.sqlite when tests run
  - hog.py
reload_modules:   # Modules reloaded before each test for isolation
  - hog
```

See the `examples` directory for more usage info.

## License

[MIT](LICENSE)

## Updating versions

- Change version in `pyproject.toml`
- `uv build`
- `uv publish`
