{"id":13501800,"url":"https://github.com/joeyespo/pytest-watch","last_synced_at":"2025-05-15T05:07:55.617Z","repository":{"id":25678437,"uuid":"29114367","full_name":"joeyespo/pytest-watch","owner":"joeyespo","description":"Local continuous test runner with pytest and watchdog.","archived":false,"fork":false,"pushed_at":"2022-07-20T09:05:05.000Z","size":134,"stargazers_count":749,"open_issues_count":49,"forks_count":55,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-14T08:11:23.629Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joeyespo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-12T02:08:20.000Z","updated_at":"2025-04-10T14:12:01.000Z","dependencies_parsed_at":"2022-07-27T05:30:08.125Z","dependency_job_id":null,"html_url":"https://github.com/joeyespo/pytest-watch","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyespo%2Fpytest-watch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyespo%2Fpytest-watch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyespo%2Fpytest-watch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyespo%2Fpytest-watch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joeyespo","download_url":"https://codeload.github.com/joeyespo/pytest-watch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254276447,"owners_count":22043867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:01:50.820Z","updated_at":"2025-05-15T05:07:50.606Z","avatar_url":"https://github.com/joeyespo.png","language":"Python","funding_links":[],"categories":["Python","👀 Status: *lookin' awesome*"],"sub_categories":["Development"],"readme":"pytest-watch -- Continuous pytest runner\n========================================\n\n[![Current version on PyPI](http://img.shields.io/pypi/v/pytest-watch.svg)][pypi]\n[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/joeyespo)\n\n**pytest-watch** a zero-config CLI tool that runs [pytest][], and re-runs it\nwhen a file in your project changes. It beeps on failures and can run arbitrary\ncommands on each passing and failing test run.\n\n\nMotivation\n----------\n\nWhether or not you use the test-driven development method, running tests\ncontinuously is far more productive than waiting until you're finished\nprogramming to test your code. Additionally, manually running `pytest` each\ntime you want to see if any tests were broken has more wait-time and cognitive\noverhead than merely listening for a notification. This could be a crucial\ndifference when debugging a complex problem or on a tight deadline.\n\n\nInstallation\n------------\n\n```bash\n$ pip install pytest-watch\n```\n\n\nUsage\n-----\n\n```bash\n$ cd myproject\n$ ptw\n * Watching /path/to/myproject\n```\n\n*Note: It can also be run using its full name `pytest-watch`.*\n\nNow develop normally and check the terminal every now and then to see if any\ntests are broken. Alternatively, pytest-watch can **notify you** when tests\npass or fail:\n\n- **OSX**\n\n  `$ ptw --onpass \"say passed\" --onfail \"say failed\"`\n\n  ```bash\n  $ ptw --onpass \"growlnotify -m \\\"All tests passed!\\\"\" \\\n        --onfail \"growlnotify -m \\\"Tests failed\\\"\"\n  ```\n\n  using [GrowlNotify][].\n\n- **Windows**\n\n  ```bat\n  \u003e ptw --onfail flash\n  ```\n\n  using [Console Flash][]\n\nYou can also run a command before the tests run, e.g. seeding your test database:\n\n```bash\n$ ptw --beforerun init_db.py\n```\n\nOr after they finish, e.g. deleting a sqlite file. Note that this script receives\nthe exit code of `pytest` as an argument.\n\n```bash\n$ ptw --afterrun cleanup_db.py\n```\n\nYou can also use a custom runner script for full `pytest` control:\n\n```bash\n$ ptw --runner \"python custom_pytest_runner.py\"\n```\n\nHere's an minimal runner script that runs `pytest` and prints its exit code:\n\n```py\n# custom_pytest_runner.py\n\nimport sys\nimport pytest\n\nprint('pytest exited with code:', pytest.main(sys.argv[1:]))\n```\n\nNeed to exclude directories from being observed or collected for tests?\n\n```bash\n$ ptw --ignore ./deep-directory --ignore ./integration_tests\n```\n\nSee the full list of options:\n\n```\n$ ptw --help\nUsage: ptw [options] [--ignore \u003cdir\u003e...] [\u003cdirectory\u003e...] [-- \u003cpytest-args\u003e...]\n\nOptions:\n  --ignore \u003cdir\u003e        Ignore directory from being watched and during\n                        collection (multi-allowed).\n  --ext \u003cexts\u003e          Comma-separated list of file extensions that can\n                        trigger a new test run when changed (default: .py).\n                        Use --ext=* to allow any file (including .pyc).\n  --config \u003cfile\u003e       Load configuration from `file` instead of trying to\n                        locate one of the implicit configuration files.\n  -c --clear            Clear the screen before each run.\n  -n --nobeep           Do not beep on failure.\n  -w --wait             Waits for all tests to complete before re-running.\n                        Otherwise, tests are interrupted on filesystem events.\n  --beforerun \u003ccmd\u003e     Run arbitrary command before tests are run.\n  --afterrun \u003ccmd\u003e      Run arbitrary command on completion or interruption.\n                        The exit code of \"pytest\" is passed as an argument.\n  --onpass \u003ccmd\u003e        Run arbitrary command on pass.\n  --onfail \u003ccmd\u003e        Run arbitrary command on failure.\n  --onexit \u003ccmd\u003e        Run arbitrary command when exiting pytest-watch.\n  --runner \u003ccmd\u003e        Run a custom command instead of \"pytest\".\n  --pdb                 Start the interactive Python debugger on errors.\n                        This also enables --wait to prevent pdb interruption.\n  --spool \u003cdelay\u003e       Re-run after a delay (in milliseconds), allowing for\n                        more file system events to queue up (default: 200 ms).\n  -p --poll             Use polling instead of OS events (useful in VMs).\n  -v --verbose          Increase verbosity of the output.\n  -q --quiet            Decrease verbosity of the output (precedence over -v).\n  -V --version          Print version and exit.\n  -h --help             Print help and exit.\n```\n\n\nConfiguration\n-------------\n\nCLI options can be added to a `[pytest-watch]` section in your\n[pytest.ini file][pytest.ini] to persist them in your project. For example:\n\n```ini\n# pytest.ini\n\n[pytest]\naddopts = --maxfail=2\n\n\n[pytest-watch]\nignore = ./integration-tests\nnobeep = True\n```\n\n\nAlternatives\n------------\n\n- [xdist][] offers the `--looponfail` (`-f`) option (and distributed testing\n  options). This instead re-runs only those tests which have failed until you\n  make them pass. This can be a speed advantage when trying to get all tests\n  passing, but leaves out the discovery of new failures until then. It also\n  drops the colors outputted by pytest, whereas pytest-watch doesn't.\n- [Nosey][] is the original codebase this was forked from. Nosey runs [nose][]\n  instead of pytest.\n\n\nContributing\n------------\n\n1. Check the open issues or open a new issue to start a discussion around\n   your feature idea or the bug you found\n2. Fork the repository, make your changes, and add yourself to [Authors.md][]\n3. Send a pull request\n\nIf you want to edit the README, be sure to make your changes to `README.md` and\nrun the following to regenerate the `README.rst` file:\n\n```bash\n$ pandoc -t rst -o README.rst README.md\n```\n\nIf your PR has been waiting a while, feel free to [ping me on Twitter][twitter].\n\nUse this software often? \u003ca href=\"https://saythanks.io/to/joeyespo\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg\" align=\"center\" alt=\"Say Thanks!\"\u003e\u003c/a\u003e\n:smiley:\n\n\n[pypi]: http://pypi.python.org/pypi/pytest-watch/\n[pytest]: http://pytest.org/\n[watchdog]: http://packages.python.org/watchdog\n[growlnotify]: http://growl.info/downloads#generaldownloads\n[console flash]: http://github.com/joeyespo/console-flash\n[pytest.ini]: https://pytest.org/latest/customize.html\n[xdist]: http://pypi.python.org/pypi/pytest-xdist\n[nosey]: http://github.com/joeyespo/nosey\n[nose]: http://nose.readthedocs.org/en/latest/\n[authors.md]: ./AUTHORS.md\n[twitter]: https://twitter.com/joeyespo\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoeyespo%2Fpytest-watch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoeyespo%2Fpytest-watch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoeyespo%2Fpytest-watch/lists"}