简体   繁体   中英

how to set config before import in pytest conftest.py?

I have myprj project, and files are as below.

$ tree myprj/
myprj/
├── prj
│   ├── __init__.py
│   ├── config.py
│   ├── my_logger.py
│   ├── my_module.py
│   └── tests
│       ├── __init__.py
│       ├── conftest.py
│       └── unit
│           ├── __init__.py
│           └── test_my_module.py
├── setup.py
└── tox.ini

config.py

LOG_FILE='/path/exists/on/production/prj.log'

my_logger.py

from prj import config
import logging

class MyLogger():
    def __init__(self):
        self.setup_logger()

    def setup_logger(self):
        logFilename = config.LOG_FILE

        file_hdlr = logging.FileHandler(logFilename)

my_module.py

from prj import my_logger

myLogger = my_logger.MyLogger()


def my_method():
    return 1

test_my_module.py

from prj import my_module

def test_my_method():
    assert 1 == my_module.my_method()

setup.py

from setuptools import setup

setup(name="Tox Testing")

tox.ini

[tox]
envlist = py35

[testenv]
deps=pytest
commands=py.test

When I run tox it fails with path not exists for log file.

GLOB sdist-make: /private/tmp/myprj/setup.py
py35 inst-nodeps: /private/tmp/myprj/.tox/dist/Tox Testing-0.0.0.zip
py35 installed: attrs==17.4.0,pluggy==0.6.0,py==1.5.2,pytest==3.3.2,six==1.11.0,Tox-Testing==0.0.0
py35 runtests: PYTHONHASHSEED='2231398989'
py35 runtests: commands[0] | py.test
========================================================================================================= test session starts =========================================================================================================
platform darwin -- Python 3.5.2, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /private/tmp/myprj, inifile:
collected 0 items / 1 errors

=============================================================================================================== ERRORS ================================================================================================================
__________________________________________________________________________________________ ERROR collecting prj/tests/unit/test_my_module.py __________________________________________________________________________________________
prj/tests/unit/test_my_module.py:1: in <module>
    from prj import my_module
prj/my_module.py:3: in <module>
    myLogger = my_logger.MyLogger()
prj/my_logger.py:6: in __init__
    self.setup_logger()
prj/my_logger.py:11: in setup_logger
    file_hdlr = logging.FileHandler(logFilename)
/Users/nile2691/.pyenv/versions/3.5.2/lib/python3.5/logging/__init__.py:1008: in __init__
    StreamHandler.__init__(self, self._open())
/Users/nile2691/.pyenv/versions/3.5.2/lib/python3.5/logging/__init__.py:1037: in _open
    return open(self.baseFilename, self.mode, encoding=self.encoding)
E   FileNotFoundError: [Errno 2] No such file or directory: '/path/exists/on/production/prj.log'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================================================================================= 1 error in 0.36 seconds =======================================================================================================
ERROR: InvocationError: '/private/tmp/myprj/.tox/py35/bin/py.test'
_______________________________________________________________________________________________________________ summary _______________________________________________________________________________________________________________
ERROR:   py35: commands failed

I get that, log file path is not exists in my local system, and it gives error.

I tried to set the LOG_FILE variable in config.py using conftest.py fixture.

conftest.py

import pytest
from prj import config


@pytest.fixture(scope="session", autouse=True)
def set_config():
    config.LOG_FILE = '/tmp/prj.log'

But still it return same error. If I am able to invoke something before start the test execution, like, py.test 's first execution step, then I can set the LOG_FILE and it would not raise error.

In the global scope of my_module.py , you create an instance my_logger.MyLogger() and in MyLogger.__init__ logging handlers are set up.

Your problem is the anti-pattern of setting up logging handlers at import time . Don't do that.

For apps, logging handlers should be configured at runtime (done by main() or whatever). For libraries, logging handlers should not be configured at all (with the exception of possibly adding a NullHandler ) - it is up to the user of your library to decide how they want handlers configured.

Note that pytest does not require that logging handlers are already configured in order to test the records logged and make assertions about log events - the caplog fixture will insert its own handlers in order to capture the logging events, so it can be used even with an unconfigured logging system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM