Test a Component in Isolation¶
Problem¶
You want pytest to render one component and assert on its HTML without standing up a full page, a route, or an HTTP request.
Solution¶
Use render_component_by_name from next.testing.
It resolves a component by name as seen from a given template path, renders it with a context mapping you supply, and returns the HTML string.
Walkthrough¶
Load the Components¶
Component discovery is a side effect, so import the components before a test resolves one.
A pytest fixture calls eager_load_components once and resets the registries around each test.
import pytest
from next.testing import eager_load_components, reset_registries
@pytest.fixture(autouse=True)
def _next_components():
reset_registries()
eager_load_components()
yield
reset_registries()
Render the Component¶
render_component_by_name takes the component name and the at path the component is referenced from.
The at path drives visibility, so pass a template inside the page tree that can see the component.
The context mapping fills the values the component template reads.
from next.testing import render_component_by_name
def test_info_card_renders_title() -> None:
html = render_component_by_name(
"info_card",
at="notes/pages/template.djx",
context={"title": "Quick start", "subtitle": "Read this first"},
)
assert "Quick start" in html
assert "info-card" in html
The helper raises LookupError when no visible component matches the name from the at path.
Assert on the Markup¶
The return value is a plain string, so any HTML assertion works.
The assert_has_class and find_anchor helpers from next.testing keep class and link checks readable.
from next.testing import assert_has_class, find_anchor, render_component_by_name
def test_info_card_marks_the_root() -> None:
html = render_component_by_name(
"info_card",
at="notes/pages/template.djx",
context={"title": "Quick start"},
)
assert_has_class(html, "info-card")
def test_info_card_links_to_detail() -> None:
html = render_component_by_name(
"info_card",
at="notes/pages/template.djx",
context={"title": "Quick start", "href": "/notes/1/"},
)
anchor = find_anchor(html, href="/notes/1/", text="Quick start")
assert 'href="/notes/1/"' in anchor
Pass a Request When the Component Needs One¶
When a component callable reads the request, build one with RequestFactory and pass it through the request keyword.
from django.test import RequestFactory
from next.testing import render_component_by_name
def test_user_badge_shows_username(db, django_user_model) -> None:
user = django_user_model.objects.create_user("ada")
request = RequestFactory().get("/")
request.user = user
html = render_component_by_name(
"user_badge",
at="notes/pages/template.djx",
request=request,
)
assert "ada" in html
Verification¶
Run the component tests.
uv run pytest -k component
Every test passes. Each component rendered on its own, with no page or route involved.
See Also¶
See also
Testing for the testing toolkit. Build a Composite Component for the component under test.