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
alert
package - Auto-run tests on save for Python and test-related files
- Insert
ipdb
orpudb
breakpoints 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 anipdb
breakpointC-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-mode
Then, 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.