pytest.el / pytest.el

Eric Larson 9ff5797 
Eric Larson e3aae71 




Eric Larson 365cb17 
Eric Larson e3aae71 
Eric Larson 9ff5797 
Eric Larson e3aae71 
















Eric Larson 9ff5797 





Eric Larson 9840047 
Eric Larson 9ff5797 



Eric Larson e3aae71 
Eric Larson 9ff5797 
Eric Larson e3aae71 


















Eric Larson b334af4 
Eric Larson e3aae71 



Eric Larson dfce4db 










Eric Larson 0944948 
Eric Larson dfce4db 




Eric Larson b1d1c9e 
Eric Larson e3aae71 


Eric Larson b1d1c9e 






Eric Larson b334af4 

Eric Larson b1d1c9e 
Eric Larson e3aae71 

Eric Larson b1d1c9e 
Eric Larson e3aae71 
Eric Larson b1d1c9e 
Eric Larson e3aae71 
Eric Larson b1d1c9e 
Eric Larson e3aae71 


Eric Larson b1d1c9e 
Eric Larson e3aae71 
Eric Larson b334af4 
Eric Larson b1d1c9e 
Eric Larson b334af4 

Eric Larson b1d1c9e 
Eric Larson b334af4 
Eric Larson b1d1c9e 
Eric Larson b334af4 

Eric Larson b1d1c9e 
Eric Larson b334af4 

Eric Larson b1d1c9e 
Eric Larson e3aae71 

Eric Larson b1d1c9e 
Eric Larson e3aae71 


Eric Larson b1d1c9e 
Eric Larson e3aae71 
Eric Larson b334af4 
Eric Larson b1d1c9e 
Eric Larson e3aae71 


Eric Larson b1d1c9e 
Eric Larson e3aae71 


Eric Larson b1d1c9e 










Eric Larson e3aae71 
Eric Larson b334af4 

Eric Larson e3aae71 



Eric Larson dfce4db 
Eric Larson e3aae71 




























Eric Larson b334af4 
Eric Larson e3aae71 





Eric Larson b334af4 
Eric Larson e3aae71 
























Eric Larson b1d1c9e 
Eric Larson 86475b7 


Eric Larson b1d1c9e 
Eric Larson e3aae71 

;;; pytest.el --- Easy Python test running in Emacs

;; Copyright (C) 2009 Eric Larson

;; Licensed under the same terms as Emacs.

;; Version: 0.2.1
;; Keywords: pytest python testing
;; URL: http://bitbucket.org/elarson/pytest.el
;; Created: 07 Oct 2011

;; This file is NOT part of GNU Emacs.

;; Licensed under the same terms as Emacs.

;;; Commentary:
;; This gives a bunch 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")
;; 
;; You can generate a script with py.test:
;;
;;   py.test --genscript=run-tests.py

;; Another option is if your global pytest isn't called "pytest" is to 
;; redefine pytest-global-name to be the command that should be used.

;; 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 "something")

;; or you can 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")))

;; Probably also want some keybindings:
;; (add-hook 'python-mode-hook
;;           (lambda ()
;;             (local-set-key "\C-ca" 'pytest-all)
;;             (local-set-key "\C-cm" 'pytest-module)
;;             (local-set-key "\C-c." 'pytest-one)
;;             (local-set-key "\C-cd" 'pytest-directory)
;;             (local-set-key "\C-cpa" 'pytest-pdb-all)
;;             (local-set-key "\C-cpm" 'pytest-pdb-module)
;;             (local-set-key "\C-cp." 'pytest-pdb-one)))

(defcustom pytest-project-names '("runtests.py")
  "The name of the script that starts the tests")

(defcustom pytest-project-root-files '("setup.py" ".hg" ".git")
  "Names of files or directories that signify the root of a
  project")

(defcustom pytest-project-root-test 'pytest-project-root
  "A function used to determine the directory the tests will be
  run from.")

(defcustom pytest-global-name "py.test"
  "The name of the py.test executable")

(defcustom pytest-cmd-flags "-x"
  "These are the flags passed to the pytest runner")
  
(defun run-pytest (&optional tests flags)
  "run pytest"
  (let* ((pytest (pytest-find-test-runner))
         (where (pytest-find-project-root))
         (tnames (if tests tests ""))
	 (cmd-flags (if flags flags pytest-cmd-flags)))
    (funcall '(lambda (command)
		(compilation-start command nil
				   (lambda (mode) (concat "*pytest*"))))
	     (format "cd %s && %s %s %s"
		     where (pytest-find-test-runner) cmd-flags tnames))))

;;; Run entire test suite
(defun pytest-all (&optional flags)
  "run all tests"
  (interactive)
  (run-pytest nil flags))

(defun pytest-failed ()
  (interactive)
  (pytest-all "-x -k "))

(defun pytest-pdb-all ()
  (interactive)
  (pytest-all "--pdb -x"))

;;; Run all the tests in a directory (and its child directories)
(defun pytest-directory (&optional flags)
  "run pytest on all the files in the current buffer"
  (interactive)
  (run-pytest (file-name-directory buffer-file-name) flags)) 

(defun pytest-pdb-directory (&optional flags)
  "run pytest on all the files in the current buffer"
  (interactive)
  (pytest-directory "--pdb -x "))

;;; Run all the tests in a file
(defun pytest-module (&optional flags)
  "run pytest (via eggs/bin/test) on current buffer"
  (interactive)
  (run-pytest buffer-file-name flags))

(defun pytest-pdb-module ()
  (interactive)
  (pytest-module "--pdb -x"))

;;; Run the test surrounding the current point
(defun pytest-one (&optional flags)
  "run pytest (via eggs/bin/test) on testable thing
 at point in current buffer"
  (interactive)
  (run-pytest (format (concat flags "-k %s %s") (pytest-py-testable) buffer-file-name) ))

(defun pytest-pdb-one ()
  (interactive)
  (pytest-one "-x "))

(defun pytest-run ()
  "Run the tests interactively asking for the test flags and
file/dir"
  (interactive)
  (let ((tests (expand-file-name 
		(read-file-name "Test directory or file: "
				(pytest-current-root))))
	(flags (read-from-minibuffer "py.test flags: ")))
    (run-pytest tests flags)))


;;; Utility functions
(defun pytest-find-test-runner ()
  (message
   (let ((result
          (reduce '(lambda (x y) (or x y))
		  (mapcar 'pytest-find-test-runner-names pytest-project-names))))
     (if result
         result
       pytest-global-name))))

(defun pytest-find-test-runner-names (runner)
  "find eggs/bin/test in a parent dir of current buffer's file"
  (message (concat "looking for " runner))
  (pytest-find-test-runner-in-dir-named
   (file-name-directory buffer-file-name) runner))

(defun pytest-find-test-runner-in-dir-named (dn runner)
  (let ((fn (expand-file-name runner dn)))
    (cond ((file-regular-p fn) fn)
      ((equal dn "/") nil)
      (t (pytest-find-test-runner-in-dir-named
          (file-name-directory (directory-file-name dn))
          runner)))))

(defun pytest-py-testable ()
  (let* ((inner-obj (inner-testable))
         (outer (outer-testable))
         ;; elisp can't return multiple values
         (outer-def (car outer))
         (outer-obj (cdr outer)))
    (cond ((equal outer-def "def") outer-obj)
          ((equal inner-obj outer-obj) outer-obj)
          (t (format "%s.%s" outer-obj inner-obj)))))

(defun inner-testable ()
  "Finds the function name for pytest-one"
  (save-excursion
    (re-search-backward
     "^ \\{0,4\\}\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t)
    (buffer-substring-no-properties (match-beginning 2) (match-end 2))))

(defun outer-testable ()
  "Finds the class for the pytest-one"
  (save-excursion
    (re-search-backward
     "^\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t)
    (let ((result
            (buffer-substring-no-properties (match-beginning 2) (match-end 2))))

      (cons
       (buffer-substring-no-properties (match-beginning 1) (match-end 1))
       result))))

(defun pytest-find-project-root (&optional dirname)
  (let ((dn
         (if dirname
             dirname
           (file-name-directory buffer-file-name))))
    (cond ((funcall pytest-project-root-test dn) (expand-file-name dn))
          ((equal (expand-file-name dn) "/") nil)
        (t (pytest-find-project-root
             (file-name-directory (directory-file-name dn)))))))

(defun pytest-project-root (dirname)
  (reduce '(lambda (x y) (or x y))
          (mapcar (lambda (d) (member d (directory-files dirname)))
                  pytest-project-root-files)))

(defun pytest-current-root ()
  (if (not (buffer-file-name))
      (expand-file-name default-directory)
    (file-name-directory (expand-file-name (buffer-file-name)))))

(provide 'pytest)

;;; pytest.el ends here
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.