ionrock / pytest-el

Run py.test on testing functions, classes, modules and entire suites in Emacs.
55 stars 26 forks source link

Does pytest.el require a runtests.py? Getting max-lisp-eval-depth error. #31

Open neilyio opened 4 years ago

neilyio commented 4 years ago

I'm new to using pytest and pytest.el, so bear with me. I'm using Spacemacs on Windows 10. I'm using the Python layer along with LSP.

I've spent an embarrassing amount of time now debugging why pytest.el keeps giving me one of two errors. Either: error: "Lisp nesting exceeds ‘max-lisp-eval-depth’" or pytest-find-test-runner-in-dir-named: Variable binding depth exceeds max-specpdl-size

Both are caused by the same thing. The function pytest-find-runner-in-dir-named is searching for a file named "runtests" (or presumably "runtests.py"), which is set by pytest-project-names. pytest-find-runner-in-dir-named recursively searches up the directory tree for "runtests".

Annoyingly, it doesn't throw an error when it reaches the drive root C:\. It just calls itself again, getting stuck in infinite recursion which ends up generating the max-eval-depth error. It would be nice if pytest.el simply threw its own error here so users can avoid cumbersome debugging.

I realize the README mentions this, suggesting to run py.test --genscript=run-tests.py to generate a "runtests" script. However, --genscript has been deprecated for 5 years, as stated here: https://github.com/pytest-dev/pytest/issues/730. It's not even a valid command in pytest anymore.

I'm confused, and I feel like I must be missing something obvious because this is part of the Python layer in Spacemacs and pytest is the most popular testing library for the most popular language in the world. So please, go easy on me, and let me know if I can help resolve this.

neilyio commented 4 years ago

It looks like pytest.el needs to use pytest's modern command line syntax. On the command line, simply calling "pytest" from my root folder works fine.

In the meantime, I'm just going to clobber pytest-cmd-format and have it return what I need, which is just the string "pytest". I also need to nuke pytest-find-test-runner, which causes this recursion problem in the first place. For any as unlucky as I, here's something to evaluate that works for me as a temporary band-aid.

(defun pytest-cmd-format (&rest _) "pytest")
(defun pytest-find-test-runner () nil)

You might consider changing the "pytest" string to add flags or whatever you usually call from the command line. I can't recommend anything, I only started using pytest this morning. In fact, because this has tripped me up all day, I've only ever run one test, an "assert True" just to see if the above hack was working.

For this reason, I'm going to avoid making a pull request because I really don't know enough about pytest. So, with that out of the way, how has anybody managed to get this working?

Is pytest.el the right library to be using? It was my first choice because it's included in Spacemacs. But I don't see how anyone using a modern version of pytest has used pytest.el successfully.

I'd love to be part of the solution. I hope someone can let me know what I missed here and how this should be fixed.

ionrock commented 4 years ago

@neilyio Oh wow! I'm really sorry for the trouble. After writing this, elpy became popular and had some testing facilities. Also, nose was still a popular choice. This module always worked for me so I didn't really need to make any changes. I ended up programming in Go more and haven't really kept up with the API changes.

I'll see if I can't get things updated, but in the meantime, I'm happy to merge any PRs that help get things working.

jonas-hagen commented 3 years ago

Thanks @neilyio! This im my workaround:

(defun pytest-cmd-format (&rest _) (concat "pytest " (projectile-project-root)))
(defun pytest-find-test-runner () nil)

It also works from files which are not in the project root.

I think that this would be easy to fix. Pytest really just needs the path to the project root or the test directory. Recursively going through the directories and finding the project root is done by projectile. But I am a elisp novice, so I cannot provide a PR.