Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 导入的类看不到Pytest环境设备_Python_Pytest_Fixtures - Fatal编程技术网

Python 导入的类看不到Pytest环境设备

Python 导入的类看不到Pytest环境设备,python,pytest,fixtures,Python,Pytest,Fixtures,我正在尝试设置pytest,以便无论何时运行测试(本地或在github操作中),环境变量都指向测试目录中的文件和位置,而不是根据用户设置的位置 问题是,如果我在test\u database函数中添加ipdb跟踪并打印os.getenv('DB\u URL'),那么夹具的更改是可见的,但是断言总是会失败,因为database对象始终具有原始的非模拟URL(在bash\u profile中设置) database.py import h5py import os class DataBase:

我正在尝试设置pytest,以便无论何时运行测试(本地或在github操作中),环境变量都指向测试目录中的文件和位置,而不是根据用户设置的位置

问题是,如果我在
test\u database
函数中添加
ipdb
跟踪并打印
os.getenv('DB\u URL')
,那么夹具的更改是可见的,但是断言总是会失败,因为
database
对象始终具有原始的非模拟URL(在
bash\u profile
中设置)

database.py

import h5py
import os

class DataBase:

    route = os.environ.get('DB_URL')

    def __init__(self):
        self.connected = False

    def connect(self):
        if not connected:
            self.db = h5py.File(self.route, 'r')
            self.connected = True
import pytest
from repo import DataBase

def test_database():
    db = DataBase()
    import ipdb; ipdb.set_trace()
    '''
    os.getenv('DB_URL') returns cwd + '/sample_db.hdf5'
    db.route returns original database, not the sample one above
    '''
    assert db.connected = False, 'DataBase must be instantiated to connected == False'
conftest.py

import os
import pytest

@pytest.fixture(autouse=True)
def mock_test_env(monkeypatch):
    cwd = os.getcwd()
    monkeypatch.setenv('DB_URL', cwd + '/sample_db.hdf5')
test_database.py

import h5py
import os

class DataBase:

    route = os.environ.get('DB_URL')

    def __init__(self):
        self.connected = False

    def connect(self):
        if not connected:
            self.db = h5py.File(self.route, 'r')
            self.connected = True
import pytest
from repo import DataBase

def test_database():
    db = DataBase()
    import ipdb; ipdb.set_trace()
    '''
    os.getenv('DB_URL') returns cwd + '/sample_db.hdf5'
    db.route returns original database, not the sample one above
    '''
    assert db.connected = False, 'DataBase must be instantiated to connected == False'

如何全局设置环境变量,使所有对象都能看到相同的环境?

正如其他人在您的评论中提到的,此赋值应避免使用类变量,因为它是一个常量,在扫描导入语句时被赋值

为了更好地理解这种情况,请尝试将
from repo import DataBase
放在方法中

def test_数据库():

像这样:

import os
import pytest

@pytest.fixture(autouse=True)
def mock_test_env(monkeypatch):
    cwd = os.getcwd()
    monkeypatch.setenv('DB_URL', cwd + '/sample_db.hdf5')

def test_database(mock_test_env):
    from repo import DataBase # <<< This here works
    db = DataBase()
    assert db.route == (os.getcwd() + '/sample_db.hdf5') # Works!

数据库
类在其当前状态下很难测试<代码>数据库。路由将在
数据库
模块导入上设置,该导入将在测试集合时发生,夹具将在稍后执行,因此monkeypatching将不起作用。您可以重构
数据库。将
路由为非类属性,或者将
数据库
导入到测试中以延迟它,但是您可能还需要一个夹具,在测试开始之前和执行
模拟测试之前重新加载模块,具体取决于测试套件的其余部分。经验法则-尝试在导入时执行尽可能少的代码。@hoefling您有关于如何重构的示例吗?也许我可以编写另一个方法,在类对象实例化时设置路由,或者编写另一个类,加载可以作为数据库类和任何其他使用环境变量的类的基类的环境变量。或者,您可以简单地在fixture中说
database.database.route='whatever'
,而不需要在你有没有关于如何重构的例子?类变量通常是常量;如果必须计算
route
的值,请将其设置为实例变量,如
connected
。更好的方法是将
route
作为参数传递到
数据库中。@pmdaly Do
self.route=os.environ.get('DB\u URL')
数据库中。
中。