I recently used Dynaconf to build a sophisticated command line interface application. As the application grew in complexity, a settings management solution was required–one which could easily be extended and overridden by end-users.
Coming from Django, I yearned for a pytest fixture which behaved like
settings
from pytest-django.
My requirements were:
- Provide deterministic settings for the test suite, impervious to environment-specific variations such as values set in environment variables (a feature of Dyanconf)
- Allow settings to be customized at the test function scope
- Clean up values between each test
The fixture itself is simple; it takes the Dynaconf
instance used in the
application and re-initializes it.
In this case, I reload the production settings file, and have added a
test-specific settings toml
file which lets us override global values.
At tear down, the settings module is wiped to avoid leaks between tests.
# conftest.py
# Import the dynaconf.Dynaconf instance
from myproject.config import settings as _settings
# This examples uses separate settings files so that the test settings
# do not get packaged.
ROOT_SETTINGS = "src/myproject/settings.toml"
TEST_SETTINGS = "tests/settings.toml"
@pytest.fixture(autouse=True)
def settings():
# Reload the "production" settings, and merge a test-specific settings
# file. Any environment variables set are ignored.
_settings.load_file(
path=[ROOT_SETTINGS, TEST_SETTINGS],
silent=False, # Yell when there are errors!
)
yield _settings
_settings.clean() # Reset / cleanup overrides
This fixture runs at each test since autouse=True
and can be pulled into
individual tests to make changes.
def test_changing_my_setting(settings):
settings.MY_SETTING = "foo"
...
For a practical example, check out: https://github.com/marcgibbons/dynaconf-pytest-example.