Theme
Version
GitHubPyPIDiscord
On this page

Testing API

djc_test

djc_test(
    django_settings: dict | None | Callable | type = None,
    components_settings: dict | None = None,
    parametrize: tuple[Sequence[str], Sequence[Sequence[Any]]] | tuple[Sequence[str], Sequence[Sequence[Any]], Iterable[None | str | float | int | bool] | Callable[[Any], None | object] | None] | None = None,
    gc_collect: bool = True
) -> Callable[[TCallable], TCallable]

See source code

Decorator for testing components from django-components.

@djc_test manages the global state of django-components, ensuring that each test is properly isolated and that components registered in one test do not affect other tests.

This decorator can be applied to a function, method, or a class. If applied to a class, it will search for all methods that start with test_, and apply the decorator to them. This is applied recursively to nested classes as well.

Example

Applying to a function:

from django_components.testing import djc_test

@djc_test
def test_my_component():
    @register("my_component")
    class MyComponent(Component):
        template = "..."
    ...

Applying to a class:

from django_components.testing import djc_test

@djc_test
class TestMyComponent:
    def test_something(self):
        ...

    class Nested:
        def test_something_else(self):
            ...

Applying to a class is the same as applying the decorator to each test_ method individually:

from django_components.testing import djc_test

class TestMyComponent:
    @djc_test
    def test_something(self):
        ...

    class Nested:
        @djc_test
        def test_something_else(self):
            ...

To use @djc_test, Django must be set up first:

import django
from django_components.testing import djc_test

django.setup()

@djc_test
def test_my_component():
    ...
ParameterTypeDescription
django_settingsdict | None | Callable | typeDjango settings, a dictionary passed to Django's @override_settings. The test runs within the context of these overridden settings.

If django_settings contains django-components settings (COMPONENTS field), these are merged. Other Django settings are simply overridden. (default: None)

components_settingsdict | NoneInstead of defining django-components settings under django_settings["COMPONENTS"], you can simply set the Components settings here.

These settings are merged with the django-components settings from django_settings["COMPONENTS"].

Fields in components_settings override fields in django_settings["COMPONENTS"]. (default: None)

parametrizetuple[Sequence[str], Sequence[Sequence[Any]]] | tuple[Sequence[str], Sequence[Sequence[Any]], Iterable[None | str | float | int | bool] | Callable[[Any], None | object] | None] | None

Parametrize the test function with pytest.mark.parametrize. This requires pytest to be installed.

The input is a tuple of:

  • (param_names, param_values) or
  • (param_names, param_values, ids)
(default: None)
gc_collectboolBy default djc_test runs garbage collection after each test to force the state cleanup. Set this to False to skip this. (default: True)

Example

from django_components.testing import djc_test

@djc_test(
    parametrize=(
         ["input", "expected"],
         [[1, "<div>1</div>"], [2, "<div>2</div>"]],
         ids=["1", "2"]
     )
)
def test_component(input, expected):
    rendered = MyComponent(input=input).render()
    assert rendered == expected

You can parametrize the Django or Components settings by setting up parameters called django_settings and components_settings. These will be merged with the respetive settings from the decorator.

Example of parametrizing context_behavior:

from django_components.testing import djc_test

@djc_test(
    components_settings={
        # Settings shared by all tests
        "app_dirs": ["custom_dir"],
    },
    parametrize=(
        # Parametrized settings
        ["components_settings"],
        [
            [{"context_behavior": "django"}],
            [{"context_behavior": "isolated"}],
        ],
        ["django", "isolated"],
    )
)
def test_context_behavior(components_settings):
    rendered = MyComponent.render()
    ...

Settings resolution:

@djc_test accepts settings from different sources. The settings are resolved in the following order:

  • Django settings:

    1. The defaults are the Django settings that Django was set up with.
    2. Those are then overriden with fields in the django_settings kwarg.
    3. The parametrized django_settings override the fields on the django_settings kwarg.

    Priority: django_settings (parametrized) > django_settings > django.conf.settings

  • Components settings:

    1. Same as above, except that the django_settings["COMPONENTS"] field is merged instead of overridden.
    2. The components_settings kwarg is then merged with the django_settings["COMPONENTS"] field.
    3. The parametrized components_settings override the fields on the components_settings kwarg.

    Priority: components_settings (parametrized) > components_settings > django_settings["COMPONENTS"] > django.conf.settings.COMPONENTS

django-components version: 0.152.0