python-tdd-mode is a lightweight, modern Emacs minor mode designed for Python developers practicing test-driven development (TDD). It streamlines your TDD workflow with one-key test execution, visual feedback via mode-line blinking, and seamless integration with Python test runners like pytest, nosetests, and Django. Requires Emacs 27.1 or later.
- Source: github.com/marcwebbie/tdd-mode
- Issues & Contributions: Report issues or contribute on GitHub
- License: GNU General Public License v3.0 (GPLv3)
—
- Run tests for the current function, class, file, or entire project
- Navigate test errors using Emacs’ built-in
next-error(M-g n) andprevious-error(M-g p) - Auto-detect and run tests for files changed in Git
- Visual feedback with mode-line blinking and optional notifications via the
alertpackage - Auto-run tests on save for Python and test-related files
- Insert
ipdborpudbbreakpoints with a single keybinding - Copy test commands, outputs, or Git diffs to the clipboard
- Fully customizable keybindings and settings
—
Get up and running with python-tdd-mode in a few steps.
Add the following to your Emacs configuration (e.g., ~/.emacs.d/init.el) using use-package and straight.el:
(use-package python-tdd-mode
:straight (python-tdd-mode :type git :host github :repo "marcwebbie/tdd-mode")
:hook (python-mode . python-tdd-mode)
:bind (:map python-tdd-mode-command-map
("C-c C-t" . python-tdd-mode-command-map))
:config
(setq python-tdd-mode-test-runner 'pytest
python-tdd-mode-auto-run-on-save t
python-tdd-mode-scroll-output t
python-tdd-mode-buffer-popup t))For MELPA or other methods, see Installation.
Open any .py file in Emacs. python-tdd-mode activates automatically via the python-mode hook.
Place your cursor in a function or class and press C-c C-t t to run the test at point. Test output appears in the *python-tdd-output* buffer.
Try these keybindings:
C-c C-t a: Run all project testsC-c C-t f: Run all tests in the current fileC-c C-t l: Re-run the last testC-c C-t r: Run tests for files changed in GitC-c C-t b: Insert anipdbbreakpointC-c C-t c: Copy test output to clipboard
In the *python-tdd-output* buffer, use n (next-error) or p (previous-error) to jump to test failures.
—
The recommended installation uses use-package with straight.el, as shown in the Quickstart. No external Emacs packages are required (Emacs 27.1+ includes all dependencies). The alert package is optional for enhanced notifications.
Once python-tdd-mode is available on MELPA, install it with:
(use-package python-tdd-mode
:ensure t
:pin melpa
:hook (python-mode . python-tdd-mode)
:bind (:map python-tdd-mode-command-map
("C-c C-t" . python-tdd-mode-command-map)))Place the python-tdd-mode files in your Emacs load path:
(use-package python-tdd-mode
:load-path "~/path/to/python-tdd-mode"
:hook (python-mode . python-tdd-mode)
:bind (:map python-tdd-mode-command-map
("C-c C-t" . python-tdd-mode-command-map))
:config
(setq python-tdd-mode-test-runner 'pytest
python-tdd-mode-auto-run-on-save t
python-tdd-mode-scroll-output t
python-tdd-mode-buffer-popup t))Clone the repository and add it to your load path:
git clone https://github.com/marcwebbie/tdd-mode.git ~/path/to/python-tdd-modeThen, add to your Emacs configuration:
(add-to-list 'load-path "~/path/to/python-tdd-mode")
(require 'python-tdd-mode)
(add-hook 'python-mode-hook #'python-tdd-mode)
(global-set-key (kbd "C-c C-t") #'python-tdd-mode-command-map)—
Customize python-tdd-mode via the :config section of use-package or M-x customize-group RET python-tdd. Available options:
| Option | Description | Default |
|---|---|---|
python-tdd-mode-test-runner | Test runner (pytest, nosetests, django) | pytest |
python-tdd-mode-notify-on-pass | Show notifications on test success | t |
python-tdd-mode-notify-on-fail | Show notifications on test failure | t |
python-tdd-mode-auto-run-on-save | Re-run last test command on file save | t |
python-tdd-mode-scroll-output | Auto-scroll the *python-tdd-output* buffer | t |
python-tdd-mode-buffer-popup | Show *python-tdd-output* buffer after tests | t |
python-tdd-mode-verbose | Enable verbose debug logging | nil |
python-tdd-mode-blink-enabled | Enable mode-line blinking for test results | t |
python-tdd-mode-blink-fail-color | Mode-line color for test failures | #F44336 |
python-tdd-mode-blink-pass-color | Mode-line color for test successes | #4CAF50 |
python-tdd-mode-blink-steps | Number of steps for mode-line fade effect | 20 |
python-tdd-mode-blink-interval | Seconds between fade steps | 0.2 |
Example to disable blinking:
(setq python-tdd-mode-blink-enabled nil)—
python-tdd-mode commands are bound under the C-c C-t prefix by default. Customize the prefix in your use-package configuration:
(use-package python-tdd-mode
:straight (python-tdd-mode :type git :host github :repo "marcwebbie/tdd-mode")
:hook (python-mode . python-tdd-mode)
:bind (:map python-tdd-mode-command-map
("C-x C-t" . python-tdd-mode-command-map)))Default keybindings:
| Keybinding | Command | Description |
|---|---|---|
C-c C-t t | python-tdd-mode-run-test-at-point | Run test at point |
C-c C-t f | python-tdd-mode-run-file-tests | Run all tests in current file |
C-c C-t a | python-tdd-mode-run-all-tests | Run all project tests |
C-c C-t r | python-tdd-mode-run-relevant-tests | Run tests for Git changes |
C-c C-t l | python-tdd-mode-run-last-test | Re-run last test |
C-c C-t c | python-tdd-mode-copy-output-to-clipboard | Copy test output to clipboard |
C-c C-t b | python-tdd-mode-insert-ipdb-breakpoint | Insert ipdb breakpoint |
C-c C-t B | python-tdd-mode-insert-pudb-breakpoint | Insert pudb breakpoint |
C-c C-t C | python-tdd-mode-copy-diff-and-output | Copy Git diff and test output to clipboard |
—
python-tdd-mode is inspired by:
- beacon.el: Visual feedback effects
- pytest.el: Pytest integration for Emacs
- auto-virtualenv.el: Python environment management
—
Found a bug or have a feature request? Please test the package in a clean Emacs environment (e.g., emacs -Q) before reporting issues. Open an issue or submit a pull request at github.com/marcwebbie/tdd-mode.
—
python-tdd-mode is licensed under the GNU General Public License v3.0. See GPLv3 for details.