pytest-djangoapp icon indicating copy to clipboard operation
pytest-djangoapp copied to clipboard

Fixture app_settings

Open jayvdb opened this issue 4 years ago • 11 comments

Most apps use global settings named APPNAME_foo.

A fixture app_settings could create a renaming proxy in which app_settings.FOO maps to settings.APPNAME_FOO.

Also , the fixture could detect https://github.com/idlesign/django-siteprefs and give those settings instead, or maybe https://github.com/idlesign/django-siteprefs should add a pytest fixture ?

jayvdb avatar Jul 28 '20 04:07 jayvdb

or maybe idlesign/django-siteprefs should add a pytest fixture ?

Most people would expect a fixture there to work with pytest-django , whereas here that wont be necessary.

jayvdb avatar Jul 28 '20 05:07 jayvdb

A tightly related problem is that an app settings module may need to be reloaded whenever a settings fixture is used and modifies settings that the app settings module uses.

I notice settings_hook and thought that might be used in this context. https://github.com/idlesign/pytest-djangoapp/pull/16 is a proof-of-concept for this, but possibly this is an incompatible mis-use of settings_hook.

My hook looks like:

def reload_app_settings(settings):
    if 'django_dunder.app_settings' in sys.modules:
        import django_dunder.app_settings
        reload(django_dunder.app_settings)

    return settings

Then after each use of settings fixture context manager, django_dunder.app_settings is reset and reflects the settings, and is restored afterwards.

This isnt ideal, as the settings passed in is ignored, and in the PR the SettingsProxy is unnecessarily .update()d with an unmodified settings dict from the hook, but it does provide a consistent mechanism that should be sufficient for most projects.

It also isnt ideal because app_settings isnt updated until __call__ (or __enter__ would be almost the same) - moving it into _set / __setattr__ would be better, but then extra logic is needed so that the hook is only invoked once for batch updates, so I haven't built it like that just yet, but would do that, and add tests, if this approach seems sensible to you.

I could have done this pytest.marks, or other mechanisms, so I am not wedded to that POC PR.

jayvdb avatar Jul 28 '20 19:07 jayvdb

What other use cases you see for that except for reloading? Also renaming proxy seems to me a bit strange, could you elaborate more on that subject?

idlesign avatar Jul 29 '20 00:07 idlesign

renaming proxy seems to me a bit strange, ..

I am not sure what you are referring to by "renaming proxy".

jayvdb avatar Jul 29 '20 02:07 jayvdb

A fixture app_settings could create a renaming proxy in which app_settings.FOO maps to settings.APPNAME_FOO.

Hm, just your very term from this issue description.

idlesign avatar Jul 29 '20 02:07 idlesign

Oh, I am anticipating a new more specific fixture for running tests against various app settings, as I anticipate that is a common use case, and it has its own complexities, and a possibly a new more specific proxy to help the new fixture.

jayvdb avatar Jul 29 '20 02:07 jayvdb

What other use cases you see for that except for reloading?

I dont have any in mind, and that does bother me a bit - I acknowledge that this doesnt seem to be a brilliant use of the existing settings_hook. The argument in its favour is that it re-uses and strengthens the existing concept, avoiding adding a new 'thing'. I'm not convinced by my own justification. I feel like reloading modules is a good new "thing" that could be an alternative focus for solving this.

The settings_hook isnt very clear about how it could be/should be used, except the use case which is currently embedded in the configuration system. It already seems to also lack clear use cases. This would add another use-case, and enables more use-cases because now the hook works with the settings fixture.

Ultimately I would like to have more use cases, and I dont mind this issue/PR held in waiting until more use-cases are provided. I suspect that if more "app settings" apps were supported, we would find uses other than reloading a module.

jayvdb avatar Jul 29 '20 02:07 jayvdb

If we are going to focus on reloading the app.app_settings as part of the settings fixture, without any "hook", it is useful to be able to determine the app_name reliably, so https://github.com/idlesign/pytest-djangoapp/pull/17 is probably the first step.

jayvdb avatar Jul 29 '20 05:07 jayvdb

settings_hook primary use so far was a preliminary one-time confguration.

By the way, why do you need app_name if you alrady know that, since you're testing that very app behaviour? Or am I missing something?

idlesign avatar Jul 30 '20 07:07 idlesign

settings_hook primary use so far was a preliminary one-time confguration.

How is "one-time" beneficial in a testing framework? ;-)

I am trying to build tests which use different app settings, with the reloading necessary not in each test method.

jayvdb avatar Jul 30 '20 08:07 jayvdb

How is "one-time" beneficial in a testing framework? ;-)

Just the same as it's useful when you configure your Django project %) I meant that now it shoots one time to make finalized project settings.

idlesign avatar Jul 30 '20 10:07 idlesign