Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Module Not Found when using pytest

Tags:

python

pytest

I have a virtualenv that uses Python 3 and am currently using pytest for testing. I've packaged a program called "process_expiring_passwords" and import this package from my general script file called "pep.py". I've also used pip in my virtualenv to install my process_expiring_passwords package.

When I go to run my tests, however, I get the following error:

ImportError while importing test module '/home/username/projects/process-expiring-passwords/tests/test_process_expiring_passwords.py'.

Hint: make sure your test modules/packages have valid Python names.

Traceback: tests/test_process_expiring_passwords.py:3: in from process_expiring_passwords import ProcessExpiringPasswords process_expiring_passwords/process_expiring_passwords.py:16: in from process_expiring_passwords.models.ProcessExpiringPasswordsLog

\ E ModuleNotFoundError: No module named 'process_expiring_passwords.models'; 'process_expiring_passwords' is not a package

Is there a particular reason why I can use my package from my pep.py general script file while pytest is unable to find said package?

The essential parts of the code related to this issue are as follows:

pep.py:

from process_expiring_passwords.process_expiring_passwords \
    import ProcessExpiringPasswords

pep = ProcessExpiringPasswords()
pep.process()

process_expiring_passwords/process_expiring_passwords.py:

from process_expiring_passwords.models.ProcessExpiringPasswordsLog \
    import ProcessExpiringPasswordsLog

class ProcessExpiringPasswords:
    def __init__(self):
        self.example = 0
    def process():
        pepl = ProcessExpiringPasswordsLog()

process_expiring_passwords/models/ProcessExpiringPasswordsLog.py:

class ProcessExpiringPasswordsLog():
    def __init__(self):
        self.example = 0

process_expiring_passwords/setup.py:

# ref: https://github.com/pypa/sampleproject/blob/master/setup.py
# ref: http://python-packaging.readthedocs.io/en/latest/minimal.html
from setuptools import setup

setup(
    name='process_expiring_passwords',
    version='0.0.1',
    packages=find_packages(),
    description='Process expiring passwords',
    license='MIT',
    install_requires=[
        'apiclient',
        'google-api-python-client',
        'httplib2',
        'mysqlclient',
        'oauth2client',
        'requests',
        'SQLAlchemy',
    ],
)

tests/test_process_expiring_passwords.py:

from process_expiring_passwords import ProcessExpiringPasswords

def test_pep():
    pep = ProcessExpiringPasswords()
    assert pep is not None

Project structure:

process_expiring_passwords
    pep.py
    process_expiring_passwords
        __init__.py
        models
            __init__.py
            ProcessExpiringPasswordsLog.py
        process_expiring_passwords.py
        setup.py
    tests
        test_process_expiring_passwords.py

Notes:

  • Updated code example and setup.py based on feedback from Matt Messersmith.
like image 506
summea Avatar asked Aug 14 '26 03:08

summea


1 Answers

Your code doesn't quite work as posted, I modified it to have the self keyword in your constructors and member functions. After that, I could get pep.py to run.

Is there a particular reason why I can use my package from my pep.py general script file while pytest is unable to find said package?

Yes, when you are in your top level process_expiring_passwords directory, you can run pep.py, because you'll be getting a "local" import of the package.

The fact that the test doens't run has little to do with pytest, and more to do with what your import statement looks like and the fact that you're not building a package:

from process_expiring_passwords import ProcessExpiringPasswords

You haven't created a package called process_expiring_passwords. You can verify this by doing python setup.py bdist_wheel (or just do sdist and unzip the tarball), unzipping the wheel, and noting that there are no packages present.

Typically, you need to install the packages python setup.py install (this plops the distributable in your site-packages), and you also have to name the packages in setup.py (find_packages() is your friend), and then your test should work (more or less) as expected.

HTH.

like image 148
Matt Messersmith Avatar answered Aug 15 '26 17:08

Matt Messersmith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!