2017-12-30 69 views
0

Flaskアプリケーションの設定ファイルのテストを書いています。システムに設定されたenv変数がテストの結果に影響しないことを確認するために、私はpytestのmonkeypatchを使って予測可能なテスト結果を作成しています。env変数を変更してfixture内のオブジェクトを正しくインポートする方法

env変数が設定されていないフィクスチャで 'config'ファイルをテストしています。テストを実行する前にmonkeypatchに変数を設定させるフィクスチャを使用しています。

両方のフィクスチャは、env変数を設定し、configオブジェクトをインポートしてからtest関数に渡します。

フィクスチャ内ではなくドキュメントの先頭にconfigオブジェクトをロードすると、両方のフィクスチャは実際のシステム環境変数に基づくバージョンを使用します。

2番目のフィクスチャがconfigオブジェクトをインポートしないようですが、cleanConfigフィクスチャで作成されたフィクスチャを再利用するようです。フィクスチャにconfigオブジェクトを再インポートさせるにはどうすればいいですか?

test_config.py:

import pytest 
from config import config 

class TestConfigSettings(object): 

@pytest.fixture(scope='function') 
def cleanConfig(config_name, monkeypatch): 
    def makeCleanConfig(config_name): 

     monkeypatch.delenv('SECRET_KEY', raising=False) 
     monkeypatch.delenv('DEV_DATABASE_URL', raising=False) 

     from config import config 
     configObject = config[config_name] 

     return configObject 
    return makeCleanConfig 


@pytest.fixture(scope='function') 
def fakeEnvConfig(config_name, monkeypatch): 
    def makeFakeEnvConfig(config_name): 

     monkeypatch.setenv('SECRET_KEY', 'fake difficult string') 
     monkeypatch.setenv('DEV_DATABASE_URL', 'postgresql://fake:5432/fakeDevUrl') 

     from config import config 
     configObject = config[config_name] 

     return configObject 
    return makeFakeEnvConfig 


def test_configObject_withDevelopmentConfig_containsCorrectSettings(self, cleanConfig): 
    configObject = cleanConfig('development') 

    assert configObject.SECRET_KEY == 'hard to guess string' 
    assert configObject.DEBUG == True 
    assert configObject.SQLALCHEMY_DATABASE_URI == None 

def test_configObject_withDevelopmentConfigAndEnvSet_copiesEnvSettings(self, fakeEnvConfig): 
    configObject = fakeEnvConfig('development') 

    assert configObject.SECRET_KEY == 'fake difficult string' 
    assert configObject.SQLALCHEMY_DATABASE_URI == 'postgresql://fake:5432/fakeDevUrl' 

Config.py:

class Config: 
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string' 

class DevelopmentConfig(Config): 
    DEBUG = True 
    SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') 

config = { 
    'default': DevelopmentConfig, 
    'development': DevelopmentConfig, 
    ... 
} 

答えて

0

私はようやく私の問題の解決策を見つけました。 reload()関数を使用することにより、コンテンツ(この場合はロードされたenv変数)を変更した後にモジュールを再度インポートすることができます。 reload()オブジェクトはモジュール上でしか動作しないので、以前にインポートしていたconfigディクショナリの代わりにconfigモジュールへのインポートを変更しなければなりませんでした。 新しいコード:

import pytest 
from importlib import reload 
import config 

class TestConfigSettings(object): 

@pytest.fixture(scope='function') 
def cleanConfig(config_name, monkeypatch): 
    def makeCleanConfig(config_name): 

     monkeypatch.delenv('SECRET_KEY', raising=False) 
     monkeypatch.delenv('DEV_DATABASE_URL', raising=False) 

     reload(config) 
     configObject = config.config[config_name] 

     return configObject 
    return makeCleanConfig 

@pytest.fixture(scope='function') 
def fakeEnvConfig(config_name, monkeypatch): 
    def makeFakeEnvConfig(config_name): 

     monkeypatch.setenv('SECRET_KEY', 'fake difficult string') 
     monkeypatch.setenv('DEV_DATABASE_URL', 'postgresql://fake:5432/fakeDevUrl') 

     reload(config) 
     configObject = config.config[config_name] 

     return configObject 
    return makeFakeEnvConfig 
関連する問題