Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/requirements.el
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
(package-initialize)

(package-refresh-contents)
(setq package-selected-packages '(f s projectile cl buttercup))
(setq package-selected-packages '(s projectile cl buttercup))

(package-install-selected-packages)

Expand Down
22 changes: 14 additions & 8 deletions lisp/pytest-process.el
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
;;; Code:

(require 'projectile)
(require 'f)
(require 's)

(require 'pytest-core)
Expand All @@ -41,29 +40,35 @@ to work in every virtual environment."

(defun pytest--python ()
"Find the python executable."
(if (f-absolute? pytest-python-executable)
(if (file-name-absolute-p pytest-python-executable)
pytest-python-executable
(executable-find pytest-python-executable)))

(defun pytest--command ()
"Construct the base command for pytest."
(cons (pytest--python) '("-m" "pytest")))

(defun pytest--execute (name command dir output-buffer)
(defun pytest--execute (name command dir output-buffer &optional error-buffer)
"Execute COMMAND asynchronously in DIR.

NAME is a name for the process.

stdout is written to OUTPUT-BUFFER, which needs to be a buffer, not a string."
stdout is written to OUTPUT-BUFFER, which needs to be a buffer, not a string.
stderr is written to ERROR-BUFFER, which also needs to be a buffer."
(let ((default-directory dir))
(start-process-shell-command name output-buffer command)))
(make-process
:name name
:buffer output-buffer
:stderr error-buffer
:connection-type 'pipe
:command command)))

(defun pytest--construct-command (args)
"Construct the pytest command using ARGS."
(let ((command (append (pytest--command) args)))
(s-join " " command)))

(defun pytest--run (&optional args dir output-buffer)
(defun pytest--run (&optional args dir output-buffer error-buffer)
"Run pytest with ARGS (if any) in the given DIR and write to OUTPUT-BUFFER.

If optional ARGS is non-nil, these are passed to pytest.
Expand All @@ -72,10 +77,11 @@ If optional DIR is non-nil, pytest is run in that directory.
Otherwise it is run in the project's root as defined by projectile or
the current working directory.

If optional OUTPUT-BUFFER is non-nil, write to that buffer."
If optional OUTPUT-BUFFER is non-nil, write stderr to that buffer.
If optional ERROR-BUFFER is non-nil, write stderr to that buffer."
(let ((command (pytest--construct-command args))
(default-directory (or dir (projectile-project-root))))
(pytest--execute "pytest" command default-directory output-buffer)))
(pytest--execute "pytest" command default-directory output-buffer error-buffer)))

(provide 'pytest-process)
;;; pytest-process.el ends here
73 changes: 73 additions & 0 deletions test.log

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions tests/test-info.el
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

(describe "a function to check if the current statement is a decorator (pytest-info--decorator-p)"
(it "detects the first line of a decorator"
(expect (with-mark-at-line buffer1 12 (pytest-info--decorator-p)) :to-be t))
(expect (with-mark-at-line buffer1 13 (pytest-info--decorator-p)) :to-be t))

(it "detects continuation lines of a decorator"
(expect (with-mark-at-line buffer1 44 (pytest-info--decorator-p)) :to-be t))
Expand All @@ -87,36 +87,35 @@
(expect (with-mark-at-line buffer2 19 (pytest-info--decorator-p)) :to-be t))

(it "does not detect function declarations"
(expect (with-mark-at-line buffer1 13 (pytest-info--decorator-p)) :to-be nil))
(expect (with-mark-at-line buffer1 14 (pytest-info--decorator-p)) :to-be nil))

(it "does not detect normal statements"
(expect (with-mark-at-line buffer1 23 (pytest-info--decorator-p)) :to-be nil)))

(describe "a function to collect information about the current position (pytest-info-current-pos)"
(it "does not collect information about a empty line at module level"
(expect (with-mark-at-line buffer1 5 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 7 (pytest-info-current-pos))
:to-equal nil))
(it "detects a plain function"
(expect (with-mark-at-line buffer1 8 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 9 (pytest-info-current-pos))
:to-equal (list filepath1 "warn"))
(expect (with-mark-at-line buffer1 8 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 10 (pytest-info-current-pos))
:to-equal (list filepath1 "warn")))
(it "detects a function with a decorator"
(expect (with-mark-at-line buffer1 12 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 13 (pytest-info-current-pos))
:to-equal (list filepath1 "failing"))
(expect (with-mark-at-line buffer1 44 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 51 (pytest-info-current-pos))
:to-equal (list filepath1 "test_skip")))
(it "detects a function with multiple decorators"
(expect (with-mark-at-line buffer1 62 (pytest-info-current-pos))
:to-equal (list filepath1 "variable"))
(expect (with-mark-at-line buffer1 59 (pytest-info-current-pos))
:to-equal (list filepath1 "variable"))
(expect (with-mark-at-line buffer1 52 (pytest-info-current-pos))
(expect (with-mark-at-line buffer1 68 (pytest-info-current-pos))
:to-equal (list filepath1 "variable")))
(it "detects a function from within the function's body"
(expect (with-mark-at-line buffer1 34 (pytest-info-current-pos))
:to-equal (list filepath1 "test_xfail")))))


(provide 'test-info)
;;; test-info.el ends here
11 changes: 11 additions & 0 deletions tests/test_example1.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
import warnings

import pytest
Expand Down Expand Up @@ -35,6 +36,11 @@ def test_xfail():
assert False


@pytest.mark.xfail(reason="xfail without a reason")
def test_xfail_reason():
assert False


@pytest.mark.xfail
def test_xpass():
warn()
Expand Down Expand Up @@ -84,3 +90,8 @@ def test_long_running():
import time

time.sleep(2)


def test_pass_with_output():
print("output")
print("error message", file=sys.stderr)
3 changes: 3 additions & 0 deletions tests/test_example3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import pytest

important_module = pytest.importorskip("lkjasdfölkja8723lkas98723_")
7 changes: 7 additions & 0 deletions tests/test_example4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import pytest

pytestmark = [pytest.mark.skipif(True, reason="skip for demonstration purposes")]


def test_pass():
pass