Pytest does not find my tests in Poetry project (VSCode finds) - pytest

I've just created my first Python package using Poetry using the usual poetry new mypackage command. My problem is that pytest does not execute any test when I run it. I'm developing using VSCode and the weird behavior is that VSCode successfully finds and executes my tests.
Poetry created a subdir called mypackage and another called tests. My test file is called tests/test_mypackage.py.
VSCode autodiscoverd the tests, and display them in the test tab. The .vscode/settings.json file has this configuration:
"python.testing.pytestArgs": [
"tests"
],
I've tried the following commands to execute pytest:
With my venv manually activated:
pytest
pytest tests
pytest tests/test_mypackage.py
cd tests;pytest test_mypackage.py
without my venv activated:
poetry run pytest
poetry run pytest tests
The behavior is always the same: nothing happens, as if pytest couldn't detect anything to run.
I've been using VSCode to run the tests, but now I want to put the code under Continuous Integration. How do I run pytest to validate my package?
UPDATE: from inside the virtual env pytest does not prints any output when run, but its return code is 1.

Poetry doesn't require to activate the venv. The command should work:
poetry run pytest
Though, you can activate the venv (with poetry shell) and run just pytest.
For the Test Explorer, I think this is still on development, officially, only Pytest and Unittest are supported, but the VSCode suggested a variable to support Poetry.
Here are the configurations that have worked to me:
{
"python.testing.cwd": ".",
"python.poetryPath": "poetry",
"python.testing.pytestEnabled": true,
"python.testing.pytestPath": ".venv/bin/pytest",
"python.testing.autoTestDiscoverOnSaveEnabled": true,
}
If you additionally needs to use environment variables, set them up in a .env file (it would be better a .env.test, but I couldn't figure it out).

pytest still does not work when running within the activated virtual environment, but I discovered that I can execute it running:
poetry run pytest
I still do not understand why it can't find the test when directly run from the command line even with the venv activated.

Related

Is there a way to rerun all Pytest tests when a file is saved?

Is there a way to automatically re-run all tests with Pytest if a file is saved in the project?
This is essentially Jest's --watch and --watchAll flags, which respectively reruns the designated test file and all test files whenever any files are saved.
Does PyTest have a similar function or flag?
If it is not too late, I have just found out about pytest-xdist
You can install it with $ pip install pytest-xdist
And run the test watcher with $ pytest -f and it looks at your directory and runs the test when files change.
More info here https://pytest-xdist.readthedocs.io/en/latest/index.html

Anaconda not launching

Whenever I try to run Anaconda Navigator (or Spyder), either from cmd or from windows, it does not launch. My mousepointer briefly shows that it is loading, but then nothing happens.
I have tried a number of solutions from other posts, but nothing worked:
I have completely uninstalled and reinstalled Anaconda
I have tried conda update -n root conda + conda update --all
I have tried conda clean --packages && conda clean --all && conda update --all
I have tried anaconda-navigator --reset
and a few more things.
My issue looks as follows:
Not a solution by itself, but: PyQt5 is bundled with Anaconda by default, so you shouldn't need to install it (again). In order to verify the presence of PyQt5:
a) execute conda list in the base environment and search for the package pyqt.
b) launch Spyder in the base environment and execute the following code:
from PyQt5.QtWidgets import QApplication, QLabel
app = QApplication([])
label = QLabel("Hello World!")
label.show()
app.exec_()
This should open an application window with the text "Hello World!".
Both would indicate, that PyQt5 is installed, and that the problem lies elsewhere.
Credit goes to JKSH for his answer to ImportError: DLL load failed while importing QtCore: The specified module could not be found.

vscode tests discovery with poetry (src layout)

Last time I've followed recommended src layout (https://hynek.me/articles/testing-packaging/) with using tox with great success.
However VSCODE tests discovery fails because src package cannot be imported. That is expected as we want to test installed package.
But how to debug my tests in vscode?
(Q author here: I've done research on that before posting the question, so sharing what I found)
Not solution
You could modify your PYTHONPATH to point to your src directory, but it breaks the main benefit from having separate src directory (read the link from OP).
Solution
Use pip install -e path/to/your/package (usually pip install -e .) to enable development mode and test versus your codebase as it would be installed.
After that your tests should be discovered properly. Otherwise it is different issue - read vs code OUTPUT console.
Note: this requires setup.py as a build backend
workaround for poetry
pyproject.toml
[build-system]
requires = [
"poetry-core>=1.0.0",
"setuptools" # to support local installations
]
then
poetry build --format sdist && tar --wildcards -xvf dist/*.tar.gz -O '*/setup.py' > setup.py
pip install -e .
Source: https://github.com/python-poetry/poetry/issues/34
TLDR: proper solution is outside of poetry scope, links to python-list discussions: https://github.com/python-poetry/poetry/issues/34#issuecomment-732478605

Conda virtual environment for IPython

I'm fairly new to the Python scene. My problem is that when I launch a jupyter notebook from an Anaconda Powershell with my DataScience virtual environment activated, the notebook does not have my virtual environment in it's PATH, and therefore cannot find some packages (like plotly and progress). The same is true when I launch VS Code from Anaconda Navigator with DataScience activated. When I run import plotly in an interactive window, I get ModuleNotFoundError: No module named ‘plotly’. But when I run this line in the terminal within VS Code, it runs without error.
So I have run the following commands in various shell/terminal sessions:
import sys
print(sys.path)
In a VS Code terminal I get:
['', 'C:\\Users\\adiad\\Anaconda3\\envs\\DataScience\\python37.zip', 'C:\\Users\\adiad\\Anaconda3\\envs\\DataScience\\DLLs', 'C:\\Users\\adiad\\Anaconda3\\envs\\DataScience\\lib', 'C:\\Users\\adiad\\Anaconda3\\envs\\DataScience', 'C:\\Users\\adiad\\Anaconda3\\envs\\DataScience\\lib\\site-packages']
In an interactive window in VS Code I get:
['C:\\Users\\adiad\\AppData\\Local\\Temp\\04e2b30c-4fc3-4aa9-9567-3aba17081a73', 'C:\\Users\\adiad\\Anaconda3\\python37.zip', 'C:\\Users\\adiad\\Anaconda3\\DLLs', 'C:\\Users\\adiad\\Anaconda3\\lib', 'C:\\Users\\adiad\\Anaconda3', '', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\adiad\\.ipython']
In a jupyter notebook running in my browser I get:
['C:\\Users\\adiad\\Anaconda3\\envs\\test', 'C:\\Users\\adiad\\Anaconda3\\python37.zip', 'C:\\Users\\adiad\\Anaconda3\\DLLs', 'C:\\Users\\adiad\\Anaconda3\\lib', 'C:\\Users\\adiad\\Anaconda3', '', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\Users\\adiad\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\adiad\\.ipython']
The IPython session don't appear to reference my virtual environment. So my question is: what do I need to do make IPython run with same environment as my terminal?
I found the following SO question which seems to answer my question, but I find it hard to believe that everyone is following this practice.
How to start an ipython shell(not notebook) within a conda or virtualenv
Here's my configuration:
conda version : 4.7.12
conda-build version : 3.18.8
python version : 3.7.3.final.0
virtual packages :
base environment : C:\Users\adiad\Anaconda3 (writable)
channel URLs : https://conda.anaconda.org/conda-forge/win-64
https://conda.anaconda.org/conda-forge/noarch
https://repo.anaconda.com/pkgs/main/win-64
https://repo.anaconda.com/pkgs/main/noarch
https://repo.anaconda.com/pkgs/r/win-64
https://repo.anaconda.com/pkgs/r/noarch
https://repo.anaconda.com/pkgs/msys2/win-64
https://repo.anaconda.com/pkgs/msys2/noarch
package cache : C:\Users\adiad\Anaconda3\pkgs
C:\Users\adiad\.conda\pkgs
C:\Users\adiad\AppData\Local\conda\conda\pkgs
envs directories : C:\Users\adiad\Anaconda3\envs
C:\Users\adiad\.conda\envs
C:\Users\adiad\AppData\Local\conda\conda\envs
platform : win-64
user-agent : conda/4.7.12 requests/2.22.0 CPython/3.7.3 Windows/10 Windows/10.0.18362
After doing further digging, my problem ought to be filed under, "knowing enough to be dangerous." My problem was ultimately caused by the fact that the jupyter package hadn't yet been installed in my new environment. So whenever I attempted to launch an IPython session of some kind, either in VS Code or in a browser, the application would look in my environment and see that the IPython packages weren't installed. It would then look to other conda environments and use the "nearest" equivalent, which was the base environment. Hence, most of the packages would load, but not all.
The fix to my problem was:
conda install jupyter
Another simple fix:
Launch CMD.exe prompt on Anaconda Navigator
Install: conda install jupyter
And
Conda install plotly

Is it possible to point tox to pull a dependency from a branch (aka use `pip -e` behind the scenes)?

How to test on py27 and py37 in tox when the py37 changes aren't packaged to pypi
The py3.7 compatible changes exist in repo branches.
They can be run by hand through pip -e installing them and running pytest without tox.
I'd like to move to running them through tox, but I can't figure out the correct string to give the deps list, or perhaps this is done in another way.
Attempted solution:
tox.ini
[tox]
envlist = py27,py37
[testenv:py27]
deps =
pytest
pytest-cov
pytest-mock
pylint
; packages specified by the setup.py cover the other dependencies for py2.7
commands =
pytest -v
[testenv:py37]
deps =
pytest
pytest-cov
pytest-mock
pylint
git+ssh//repo_url/location1.git#branchname_that_supports_py37
git+ssh//repo_url/location2.git#branchname_that_supports_py37
git+ssh//repo_url/location3.git#branchname_that_supports_py37
git+ssh//repo_url/location4.git#branchname_that_supports_py37
git+ssh//repo_url/location5.git#branchname_that_supports_py37
git+ssh//repo_url/location6.git#branchname_that_supports_py37
git+ssh//repo_url/location7.git#branchname_that_supports_py37
git+ssh//repo_url/location8.git#branchname_that_supports_py37
commands =
pytest -v
For VCS URLs pip needs to know the name of the package that should be provided with #egg=name:
git+ssh//repo_url/location1.git#branchname_that_supports_py37#egg=package1
Otherwise your tox.ini looks good. I use the same approach, for example.