pytest running with another version of python
Bottom line: run
python -m pytest
, orpy.test-<version>
if your alternative Python andpytest
are installed with system package manager, or- if your alternative Python has been installed with
pyenv
, switch withpyenv
to that version and make sure you havepytest
installed for it. Then you can just runpytest
.- since the
pip
executable is also among the ones being switched, you need to switch to the alternative Python before installingpytest
for it, too.
- since the
As I can see, /usr/bin/pytest
(that belongs to the system package manager's python-pytest
package) has a shebang !#/usr/bin/python
since it corresponds to the system python's installation.
pyenv
, as its README.md
says, does not replace /usr/bin/python
- because it indeed should not be replaced to avoid breaking system packages.
Instead, it adds its directory to PATH
and inserts a launcher there (called "shim") which is what gets invoked when you type "python
". As you probably guessed, this hack is ignored by a shebang like the above - as it should.
- Running
python -m pytest
will make whicheverpython
that launches itself use the package from its installation. - Alternatively,
pytest
for your other Python version may include versioned executables on thePATH
namedpy.test-<version>
(e.g.py.test-3
orpy.test-3.6
) depending on the way you installed it.- If it's from a system package manager's package for nonstandard python - like
python36-pytest
- this is virtually guaranteed. - I checked that if you install a version with
pip
, it only creates an unversioned executable (though you can create a versioned one yourself). Moreover, if you install the same package for a different Python version but with the same--prefix
, it will overwrite the existing one's executable!
- If it's from a system package manager's package for nonstandard python - like
pyenv
's suggested way seems to be to install allpython
versions of interest and packages for them under~/.pyenv/versions
.- This is not applicable for the system's Python but the default
/usr/local
can be used for it. - Once you switch to an alternative Python version, it claims to create shims for all scripts (including
pip
!) that are currently installed for that version, so invoking those scripts without a path would run those shims.- So, if a package (and thus its script) is not installed for the alternative version but installed for system version, trying to run its executable would "fall through" to
/usr/local
with just the result you're seeing now.
- So, if a package (and thus its script) is not installed for the alternative version but installed for system version, trying to run its executable would "fall through" to
- This is not applicable for the system's Python but the default
Pytest how to specify python version per test function
pytest allows you to conditionally skip tests by using the skipif
decorator.
@pytest.mark.skipif(sys.version_info >= (3, 9))
def test_base_callback_call():
...
https://docs.pytest.org/en/6.2.x/skipping.html#id1
Pytest and Python 3
I found a workaround:
- Installed
python3-pip
using aptitude, which created/usr/bin/pip-3.2
. - Next
pip-3.2 install pytest
which re-installed pytest, but under a python3.2 path. - Then I was able to use
python3 -m pytest somedir/sometest.py
.
Not as convenient as running py.test directly, but workable.
Run every pytest test function simultaneously with another function
Fixtures are a perfect use case for this.
See the following hypothetical example --
import pytest
@pytest.fixture
def record_video():
record.start()
yield
record.stop()
@pytest.fixture(scope="session")
def generate_report():
yield
report.make()
Running one test with different versions of fixture
I think parametrized fixture is what will work for you very well:
import pytest
@pytest.fixture
def backends():
"""Mapping of possible backend ids to their constructor functions."""
return {
1: connect_to_backend_1,
2: connect_to_backend_2
}
@pytest.fixture(scope="session", params=[1, 2])
def backend(request, backends):
"""Parametrized backend instance."""
return backends[request.param]()
def test_contract_method_1(backend):
result = run_contract_method_1()
assert result == backend.get_data()
def test_contract_method_2(backend):
result = run_contract_method_2()
assert result == backend.get_data()
This is not live yet, but at least you'll get better understanding if you read this fully:
https://bitbucket.org/pytest-dev/pytest/src/da9d03b1f91d63ec97a989804bacfc03204b0e12/doc/en/fixture.txt?at=default
Related Topics
How to Protect My Python Scripts on Raspberry Pi
Instance Variables VS. Class Variables in Python
Getting a List of Values from a List of Dicts
Understanding _Get_ and _Set_ and Python Descriptors
Convert Pyspark String to Date Format
How to Call a Python Function from Node.Js
Label Encoding Across Multiple Columns in Scikit-Learn
How to Enable Cors on Django Rest Framework
How to Pass Another Entire Column as Argument to Pandas Fillna()
Detect Face Then Autocrop Pictures
Convert Binary to Ascii and Vice Versa
How to Keep Python Print from Adding Newlines or Spaces
Pg_Config Executable Not Found
Formatting Floats Without Trailing Zeros
Creating a Dictionary from a CSV File
How to Remove Convexity Defects in a Sudoku Square
Importing a CSV File into a SQLite3 Database Table Using Python