/pytest-el

Run py.test on testing functions, classes, modules and entire suites in Emacs.

Primary LanguageEmacs Lisp

pytest.el

`pytest.el` provides a set of functions that handle running pytest on a particular buffer or part of a buffer. This started as a direct port of nosemacs (https://bitbucket.org/durin42/nosemacs). A special thanks to Jason Pellerin and Augie Fackler for writing nose.el.

Installation

In your Emacs config:

(require 'pytest)

If you don’t use a global installation of py.test (ie in virtualenv) then add something like the following that points to either the non-global version or a test runner script.

(add-to-list 'pytest-project-names "my/crazy/runner")

For example, you can generate a script with py.test:

py.test --genscript=run-tests.py

A much better pattern is to use a `.dir-locals.el` file to define the test runner executable. For example, I use a small library called xe for finding the current project’s virtualenv. Here is what `.dir-locals.el` would look like, using xe.

;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

((python-mode
  (pytest-global-name . "xe test")
  (pytest-cmd-flags . "")))

By default, the root of a project is found by looking for any of the files ‘setup.py’, ‘.hg’ and ‘.git’. You can add files to check for to the file list:

(add-to-list 'pytest-project-root-files ".bzr")

You can also change the project root test to detect in some other way whether a directory is the project root:

(setq pytest-project-root-test (lambda (dirname) (equal dirname "foo")))

Minor mode

pytest.el defines a minor mode that can be enabled on buffers visiting test modules.

pytest-mode considers a file as being a test module if its name matches the regular expression pytest-test-module-regex (test_*.py by default).

The minor mode defines a keymap for running tests:

C-c t a:   pytest-all
C-c t d:   pytest-directory
C-c t m:   pytest-module
C-c t c:   pytest-class
C-c t .:   pytest-one
C-c t r:   pytest-rerun-last
C-c t d:   pytest-directory
C-c t p a: pytest-pdb-all
C-c t p m: pytest-pdb-module
C-c t p c: pytest-pdb-class
C-c t p .: pytest-pdb-one

The prefix C-c t can be changed setting a diferent value for the variable pytest-mode-keymap-prefix before enabling the minor mode for the first time.

In order to conditionally enable the minor mode when visiting a test module add the function pytest-mode-enable-if-test-module to the hook python-mode-hook.

(eval-after-load "pytest"
  '(progn
     (setq pytest-mode-keymap-prefix "C-c m t")
     (add-hook 'python-mode-hook 'pytest-mode-enable-if-test-module)))

Running tests for the current module

pytest.el allows you to run tests for the current module, in opposition to running test from the current module.

In order to find the module that contains the tests for the current module, pytest-run-tests-for-current-module calls the functions in the variable pytest-test-module-name-candidate-functions until one returns the path for an existing file. The tests from that file are executed. If no function returns a valid candidate an user error is signaled.

By default pytest.el will run the tests in the current module if it’s already a test module, and then look for the module <src>/tests/test_<module>.py and the module <pkg>/tests/test_<module>.py.

If your project uses other conventions you can easily define a new candidate generator function and customize pytest. For extra details C-h f pytest-run-tests-for-current-module.