Using own decorators with pytest - python-3.x

I would like to use a "helper" decorator in multiple pytest test files:
min311 = pytest.mark.skipif(sys.version_info < (3,11), reason="You need at least Python v3.11 to run this test")
...
#min311
def test_...
Which is the best place for min311? It is not imported automatically from conftest.py.

Given this layout:
.
├── src
│   ├── conftest.py
│   └── mycode
│   ├── __init__.py
│   └── main.py
└── tests
├── conftest.py
├── __init__.py
└── test_mycode.py
4 directories, 6 files
If I define min311 in tests/conftest.py, then in test_mycode.py I can write:
from tests.conftest import min311
#min311
def test_something():
...
This assumes that we are running pytest from the top-level directory.
This also works for the simpler layout:
.
├── conftest.py
├── mycode
│   ├── __init__.py
│   └── main.py
└── tests
├── conftest.py
├── __init__.py
└── test_mycode.py
If you don't want to import from conftest directly, just move the decorator definition somewhere more palatable. I've seen a number of projects that include something like a test_helpers module in their code:
.
├── conftest.py
├── mycode
│   ├── __init__.py
│   ├── main.py
│   └── test_helpers.py
└── tests
├── conftest.py
└── test_mycode.py
Then you can:
from mycode.test_helpers import min311

Related

Alias path name in VS Code

I have a folder structure as
└── project
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
└── module3.py
From module1.py I can currently import something from module3.py with from package2.module3 import abc. However I want to alias package2 as something else without changing the name of the folder so that I can write from new_name.module3 import abc and I want VS Code to recognize the import path.
Add a module new_name (i.e. a file new_name.py) with the following content:
__path__ = [
"package2",
]
For more info, see Packages and the role of path.

How to solve python moduleNotFoundError

I'm having trouble understanding the module layout in python. Here is my directory / file structure
Project2.1/
├── project2
│   ├── data_mining
│   │   ├── process.py
│   │   └── __init__.py
│   └── __init__.py
└── tests
   ├── data
   │   └── data.csv
   ├── data_mining
   │   ├── __init__.py
   │   └── test_process.py
   └── __init__.py
File test_process.py, contains the following import
from project2.data_mining.process import ClassP
Run file tests/data_mining/test_proecss.py using the following command from directory Project2.1
$ cd Project2.1
$ python3 tests/data_mining/test_process.py
Generates the error
File "tests/data_mining/test_process.py", line 7, in <module>
from project2.data_mining.process import ClassP
ModuleNotFoundError: No module named 'project2'
ClassP is a class inside project2/data_mining/process.py
Since you are in the data_mining directory of tests folder , only those files inside the data_mining folder are accessible directly, and you can't type the path of module with from, you need to add the path of the data_mining folder of project2 , so get the exact path of data_mining (of project2 )
and
import sys
sys.path.append(exact path)
from process import ClassP
this will append the path of that folder and make all files inside it accessible to the import system
also remeber we don't use .py or any extension while importing
it is just like importing any other module from random import randint for instance
:D

python patch not patching out tested class

I'm trying to set up some unit tests for gateway.py. When I call the below test code once im inside gateway.py(debugging) it doesn't seem to mock out the os.environ call
os.environ
environ({'PATH': '.....'})
os.environ['x']
Traceback (most recent call last):
File "/home/justin/.IdeaIC2019.3/config/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
exec(exp, global_vars, local_vars)
File "<input>", line 1, in <module>
File "/usr/lib/python3.6/os.py", line 669, in __getitem__
raise KeyError(key) from None
KeyError: 'x'
test file:
import unittest
from unittest.mock import patch
import mock
from httmock import urlmatch, HTTMock
import requests
class TestGateway(unittest.TestCase):
#patch('gateway.os.environ', mock.MagicMock(return_value="mock_env_var"))
def test_zoho_event(self, mock_os):
mock_os.environ.assert_called()
my directory structure:
.
├── docker
│   ├── flask
│   │   ├── Dockerfile
│   │   └── prod_vars.env
│   └── nginx
│   ├── x.gateway.com.au.conf
│   ├── Dockerfile
│   └── nginx.conf
├── docker-compose.yml
├── gateway.ini
├── gateway.py
├── Jenkinsfile
├── logs
│   └── gateway.log
├── __pycache__
│   ├── gateway.cpython-36.pyc
│   ├── test_gateway.cpython-36.pyc
│   └── wsgi.cpython-36.pyc
├── requirements.txt
├── test_gateway.py
└── wsgi.py
I have reread https://docs.python.org/3/library/unittest.mock.html#where-to-patch many times and I am sure I am patching where the function is loaded from which is inside gateway.py. Not sure what im missing?

How to import from a project folder that is dedicated to containing packages?

I need to write a bunch of libraries for the current project I am working on. The support libraries are called WestPond and EastPond and the main project is called AtlanticOcean. I don't want to install WestPond and EastPond to my site-packages folder because I want site-packages to be only for packages that weren't written by me. The folder sturcture looks like:
atlantic_ocean/
│
├── AtlanticOcean/
│ └── main.py
│
├── scripts/
│ └── send_report.py
│
├── requirements.txt
│
│
└── src/
│
├── WestPond
│ └── main.py
│
└── EastPond
└── main.py
Inside of atlantic_ocean\src\WestPond\main.py I have:
def main():
return ['salmon', 'trout', 'tuna']
Inside of atlantic_ocean\AtlanticOcean\main.py I have:
import sys
src_path = r'C:\Users\robert_levey\pycharmprojects\atlantic_ocean\src'
sys.path.append(src_path)
from WestPond.main import main as west_pond_species
I feel like the current sys.path.append method is ugly and unpythonic. Is there a better way to import all the packages inside the src folder?
Ideally, there would be something like:
from .src import WestPond, EastPond

Python 3 unittest doesn't load test suite

I am trying to run tests after loading a test suite from a module and it doesn't seem to start any of test cases. I get this result:
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
This is my project tree:
├── Tests
│   ├── NetworkTests
│   │   ├── AuthenticationTests.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── __init__.py
│   ├── __pycache__
│   └── test_runner.py
test_runner.py:
from unittest.loader import TestLoader
from unittest.runner import TextTestRunner
from unittest.suite import TestSuite
from Tests import NetworkTests
loader = TestLoader()
suite = TestSuite((
loader.loadTestsFromModule(NetworkTests)
))
runner = TextTestRunner()
runner.run(suite)
NetworkTests/AuthenticationTests.py:
import unittest
from common.testing_utils import NetworkingTestMixin
class AuthenticationTestCase(NetworkingTestMixin, unittest.TestCase):
def test_authentication_success(self):
pass
def test_authentication_fail(self):
pass
I call python3 Tests/test_runner.py command to run these tests. When I inspect this with debugger the suite is empty.
OK, I've played around with unittest I don't have slightest idea why it works, however, this is what solved the problem (I've tried previously something similar but to no avail):
import unittest
# Leave this as it is. Otherwise tests will fail
from NetworkTests import *
unittest.main()
It displays an error message that it can't find NetworkTests, but it does somehow.

Resources