add a debug-test recipe that breaks at the start of tests and runs UI in headed mode - fix --trace to work with unittest style tests

This commit is contained in:
Brian Kohan 2025-12-12 10:57:33 -08:00
parent e0011e8abb
commit b16352cc95
No known key found for this signature in database
GPG Key ID: 5C6CE8BA38C43FC1
3 changed files with 111 additions and 35 deletions

View File

@ -96,6 +96,22 @@ just test src/polymorphic/tests/test_admin.py
just test src/polymorphic/tests/test_admin.py::PolymorphicAdminTests::test_admin_registration
```
### Running UI Tests
Make sure you have playwright installed:
```bash
just install-playwright
```
If you want to see the test step through the UI actions you can run the test like so:
```bash
just debug-test -k <test_name>
```
This will open a browser and the debugger at the start of the test, you can then ``next`` through and see the UI actions happen.
## Versioning
[django-polymorphic](https://pypi.python.org/pypi/django-polymorphic) strictly adheres to [semantic versioning](https://semver.org).
@ -111,40 +127,44 @@ just release x.x.x
## Just Recipes
```bash
build # build docs and package
build-docs # build the docs
build-docs-html # build html documentation
build-docs-pdf # build pdf documentation
check # run all static checks
check-docs # lint the documentation
check-docs-links # check the documentation links for broken links
check-format # check if the code needs formatting
check-lint # lint the code
check-package # run package checks
check-readme # check that the readme renders
check-types # run static type checking
clean # remove all non repository artifacts
clean-docs # remove doc build artifacts
clean-env # remove the virtual environment
clean-git-ignored # remove all git ignored files
coverage # generate the test coverage report
docs # build and open the documentation
docs-live # serve the documentation, with auto-reload
build # build docs and package
build-docs # build the docs
build-docs-html # build html documentation
build-docs-pdf # build pdf documentation
check # run all static checks
check-docs # lint the documentation
check-docs-links # check the documentation links for broken links
check-format # check if the code needs formatting
check-lint # lint the code
check-package # run package checks
check-readme # check that the readme renders
check-types # run static type checking
clean # remove all non repository artifacts
clean-docs # remove doc build artifacts-
clean-env # remove the virtual environment
clean-git-ignored # remove all git ignored files
coverage # generate the test coverage report
debug-test *TESTS # debug a test - (break at test start/run in headed mode)
docs # build and open the documentation
docs-live # serve the documentation, with auto-reload
fetch-refs LIB
fix # fix formatting, linting issues and import sorting
format # format the code and sort imports
install *OPTS # update and install development dependencies
install-docs # install documentation dependencies
install-precommit # install git pre-commit hooks
install_uv # install the uv package manager
lint # sort the imports and fix linting issues
manage *COMMAND # run the django admin
open-docs # open the html documentation
precommit # run the pre-commit checks
release VERSION # issue a release for the given semver string (e.g. 2.1.0)
run +ARGS # run the command in the virtual environment
setup python="python" # setup the venv and pre-commit hooks
sort-imports # sort the python imports
test *TESTS # run tests
validate_version VERSION # validate the given version string against the lib version
fix # fix formatting, linting issues and import sorting
format # format the code and sort imports
install *OPTS # update and install development dependencies
install-docs # install documentation dependencies
install-precommit # install git pre-commit hooks
install_uv # install the uv package manager
lint # sort the imports and fix linting issues
make-test-migrations # regenerate test migrations using the lowest version of Django
manage *COMMAND # run the django admin
open-docs # open the html documentation
precommit # run the pre-commit checks
release VERSION # issue a release for the given semver string (e.g. 2.1.0)
run +ARGS # run the command in the virtual environment
setup python="python" # setup the venv, pre-commit hooks and playwright dependencies
sort-imports # sort the python imports
test *TESTS # run tests
test-db DB_CLIENT="dev" *TESTS
test-lock +PACKAGES # lock to specific python and versions of given dependencies
validate_version VERSION # validate the given version string against the lib version
```

View File

@ -1,5 +1,57 @@
import inspect
def pytest_configure(config):
# stash it somewhere global-ish
from polymorphic import tests
tests.HEADLESS = not config.getoption("--headed")
def first_breakable_line(obj) -> tuple[str, int]:
"""
Return the absolute line number of the first executable statement
in a function or bound method.
"""
import ast
import textwrap
func = obj.__func__ if inspect.ismethod(obj) else obj
source = inspect.getsource(func)
source = textwrap.dedent(source)
filename = inspect.getsourcefile(func)
assert filename
_, start_lineno = inspect.getsourcelines(func)
tree = ast.parse(source)
for node in tree.body[0].body:
if (
isinstance(node, ast.Expr)
and isinstance(node.value, ast.Constant)
and isinstance(node.value.value, str)
):
continue
return filename, start_lineno + node.lineno - 1
# fallback: just return the line after the def
return filename, start_lineno + 1
def pytest_runtest_call(item):
# --trace cli option does not work for unittest style tests so we implement it here
test = getattr(item, "obj", None)
if item.config.option.trace and inspect.ismethod(test):
from IPython.terminal.debugger import TerminalPdb
try:
file = inspect.getsourcefile(test)
assert file
dbg = TerminalPdb()
dbg.set_break(*first_breakable_line(test))
dbg.cmdqueue.append("continue")
dbg.set_trace()
except (OSError, AssertionError):
pass

View File

@ -193,6 +193,10 @@ test-db DB_CLIENT="dev" *TESTS:
uv sync --group {{ DB_CLIENT }}
@just run pytest --cov-append {{ TESTS }}
# debug a test - (break at test start/run in headed mode)
debug-test *TESTS:
@just run pytest -s --trace --pdbcls=IPython.terminal.debugger:Pdb --headed {{ TESTS }}
# run the pre-commit checks
precommit:
@just run pre-commit