Skip to content

Testing API¤

djc_test ¤

djc_test(
    django_settings: Union[Optional[Dict], Callable, Type] = None,
    components_settings: Optional[Dict] = None,
    parametrize: Optional[
        Union[
            Tuple[Sequence[str], Sequence[Sequence[Any]]],
            Tuple[
                Sequence[str],
                Sequence[Sequence[Any]],
                Optional[Union[Iterable[Union[None, str, float, int, bool]], Callable[[Any], Optional[object]]]],
            ],
        ]
    ] = None,
    gc_collect: bool = True,
) -> Callable

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.

Examples:

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():
    ...

Arguments:

  • django_settings: Django 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.

  • components_settings: Instead 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"].

  • parametrize: 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)

    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()
        ...
    

  • gc_collect: By default djc_test runs garbage collection after each test to force the state cleanup. Set this to False to skip this.

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