Testing¶
pythonnative.testing renders components without a device or
simulator. render mounts an element
into an in-memory FakeBackend
and returns a RenderResult with
Testing Library-style queries and event helpers;
render_hook does the same for a
bare hook.
Test utilities: render components without a device.
import pythonnative as pn
from pythonnative.testing import render, render_hook
@pn.component
def Counter():
count, set_count = pn.use_state(0)
return pn.Column(
pn.Text(f"Count: {count}"),
pn.Button("+", on_press=lambda: set_count(count + 1)),
)
def test_counter_increments():
result = render(Counter())
result.press(result.get_by_text("+"))
assert result.get_by_text("Count: 1")
def test_use_state():
hook = render_hook(lambda: pn.use_state("a"))
hook.act(lambda: hook.current[1]("b"))
assert hook.current[0] == "b"
rendermounts an element into aFakeBackendand returns aRenderResultwith Testing Library-style queries (get_by_text,get_by_test_id,get_by_label,get_by_type) and event helpers (press,fire,change_text,back).render_hookruns a hook in a throwaway component.settlepumps the framework loop so async work (resources, queries, transitions) completes.FakeHoststands in for a native screen host so root stack navigators can be tested.
Modules:
| Name | Description |
|---|---|
backend |
In-memory backend implementing the batched mutation protocol. |
harness |
Render components into a fake backend and query the result. |
Classes:
| Name | Description |
|---|---|
FakeBackend |
Tag-table backend recording one tuple per applied mutation. |
FakeView |
Simulated native view: type, props, children, and last frame. |
FakeHost |
A |
HookResult |
Handle returned by |
RenderResult |
Handle to a mounted tree: queries, events, re-render, unmount. |
Functions:
| Name | Description |
|---|---|
render |
Mount |
render_hook |
Run |
settle |
Pump the framework loop and flush pending renders until everything is idle. |
Attributes:
| Name | Type | Description |
|---|---|---|
DEFAULT_INTRINSIC |
Dict[str, Tuple[float, float]]
|
Intrinsic sizes reported for content-sized leaves (what platform measure hooks would return). |
DEFAULT_INTRINSIC
module-attribute
¶
DEFAULT_INTRINSIC: Dict[str, Tuple[float, float]] = {
"Text": (60.0, 16.0),
"Button": (80.0, 32.0),
"Image": (40.0, 40.0),
"TextInput": (120.0, 32.0),
"TabBar": (320.0, 49.0),
}
Intrinsic sizes reported for content-sized leaves (what platform measure hooks would return).
FakeBackend
¶
Tag-table backend recording one tuple per applied mutation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
intrinsic
|
Optional[Dict[str, Tuple[float, float]]]
|
Override the intrinsic sizes used by
|
None
|
Methods:
| Name | Description |
|---|---|
apply_mutations |
Apply one committed batch to the view tree, recording each op in |
resolve_view |
Return the live view registered under |
measure_intrinsic |
Return the configured intrinsic size for the view's type and record the call in |
command |
Record an imperative view command in |
set_animated_property |
Record an animated property write in |
start_animation |
Decline native animation (return |
cancel_animation |
Do nothing; the fake never starts native animations. |
live_view_count |
Return how many views are currently registered (created and not yet destroyed). |
ops_of |
Every recorded op tuple whose first element is |
detached_views |
Live views never inserted into a parent ( |
apply_mutations
¶
Apply one committed batch to the view tree, recording each op in ops and batches.
Raises AssertionError on malformed transactions (unknown tags, double creates or destroys).
resolve_view
¶
Return the live view registered under tag, or None.
measure_intrinsic
¶
Return the configured intrinsic size for the view's type and record the call in measure_calls.
Unknown tags and types without an entry measure as (0.0, 0.0); the constraints are ignored.
command
¶
Record an imperative view command in commands and return None.
set_animated_property
¶
Record an animated property write in animated without touching props.
start_animation
¶
Decline native animation (return False) so animations run through the Python driver.
cancel_animation
¶
Do nothing; the fake never starts native animations.
FakeView
¶
Simulated native view: type, props, children, and last frame.
Attributes:
| Name | Type | Description |
|---|---|---|
tag |
The reconciler-assigned tag (use with |
|
type_name |
Native type, e.g. |
|
props |
Dict[str, Any]
|
Native-safe props (event callbacks are stripped; they
live in the event registry keyed by |
children |
List[FakeView]
|
Child views in order. |
frame |
Tuple[float, float, float, float]
|
|
Methods:
| Name | Description |
|---|---|
walk |
Yield this view and every descendant, depth-first. |
find_all |
Every view in this subtree matching a type name or predicate. |
find_first |
Return the first view in this subtree matching a type name or predicate, or |
dump |
Indented, human-readable subtree (for failing-test output). |
text
property
¶
Visible text for text-bearing views (Text.text, Button.title, TextInput.value).
walk
¶
Yield this view and every descendant, depth-first.
With include_hidden=False subtrees under a display: "none"
view are skipped (what a user can see).
find_all
¶
Every view in this subtree matching a type name or predicate.
find_first
¶
Return the first view in this subtree matching a type name or predicate, or None.
FakeHost
¶
A HostNavigator that records native screen operations.
Pass as render(..., host=FakeHost()) to render a root stack the
way a device would: pushes are recorded in pushed instead of
creating screens in-tree. set_focused simulates the platform
covering / revealing the screen.
Methods:
| Name | Description |
|---|---|
initial_navigation_state |
Return the |
push_screen |
Record the push in |
pop_screens |
Record the requested pop |
replace_screen |
Record the replacement in |
reset_screens |
Record the stack reset in |
set_screen_options |
Append a copy of |
add_focus_listener |
Register a focus callback fired by |
set_focused |
Simulate the platform covering ( |
Attributes:
| Name | Type | Description |
|---|---|---|
title |
Optional[str]
|
The most recent |
initial_navigation_state
¶
Return the initial_state the host was constructed with (None for a fresh root).
push_screen
¶
Record the push in pushed instead of creating a native screen.
replace_screen
¶
Record the replacement in replaced instead of swapping a native screen.
reset_screens
¶
Record the stack reset in resets instead of rebuilding native screens.
set_screen_options
¶
Append a copy of options to options (see the title property).
add_focus_listener
¶
Register a focus callback fired by set_focused; returns an unsubscribe callable.
HookResult
¶
HookResult(
result: RenderResult,
box: Dict[str, Any],
rerender: Callable[..., None],
)
Bases: Generic[T]
Handle returned by render_hook.
Attributes:
| Name | Type | Description |
|---|---|---|
current |
T
|
The hook's most recent return value. |
Methods:
| Name | Description |
|---|---|
act |
Run |
rerender |
Re-run the hook with new arguments. |
settle |
Flush pending renders and async work started by the hook. |
unmount |
Unmount the harness component, running the hook's effect cleanups. |
RenderResult
¶
RenderResult(
reconciler: Any,
backend: FakeBackend,
wrap: Callable[[Node], Element],
)
Handle to a mounted tree: queries, events, re-render, unmount.
Query methods come in three flavors, mirroring Testing Library:
get_by_* returns exactly one match or raises LookupError
(with the tree dumped in the message), query_by_* returns the
match or None, get_all_by_* returns every match. Matchers
are exact strings, compiled regexes, or predicates. Views inside a
display: "none" subtree (inactive tabs, covered stack screens)
are skipped unless hidden=True is passed.
Methods:
| Name | Description |
|---|---|
views |
Every live view, root first (includes detached |
dump |
Indented text rendering of the live tree. |
text |
Visible strings in document order. |
get_all_by_text |
Return every view whose visible text matches |
get_by_text |
Return the single view whose visible text matches |
query_by_text |
Return the first view whose visible text matches |
get_all_by_test_id |
Return every view whose |
get_by_test_id |
Return the single view whose |
query_by_test_id |
Return the first view whose |
get_all_by_label |
Return every view whose |
get_by_label |
Return the single view whose |
query_by_label |
Return the first view whose |
get_all_by_type |
Return every view of native type |
get_by_type |
Return the single view of native type |
query_by_type |
Return the first view of native type |
fire |
Dispatch |
press |
Fire |
change_text |
Fire |
back |
Simulate the system back action; returns whether a handler consumed it. |
settle |
Flush pending renders and async work (see |
rerender |
Reconcile a new root element (new props from outside the tree). |
unmount |
Unmount the tree, running effect cleanups and destroying every view. |
Attributes:
| Name | Type | Description |
|---|---|---|
root |
Optional[FakeView]
|
The root native view ( |
views
¶
Every live view, root first (includes detached Portal overlays).
get_all_by_text
¶
Return every view whose visible text matches matcher (exact=False matches substrings).
get_by_text
¶
Return the single view whose visible text matches matcher; raise LookupError otherwise.
query_by_text
¶
query_by_text(
matcher: Matcher,
*,
exact: bool = True,
hidden: bool = False
) -> Optional[FakeView]
Return the first view whose visible text matches matcher, or None.
get_all_by_test_id
¶
Return every view whose test_id prop matches matcher.
get_by_test_id
¶
Return the single view whose test_id prop matches matcher; raise LookupError otherwise.
query_by_test_id
¶
Return the first view whose test_id prop matches matcher, or None.
get_all_by_label
¶
Return every view whose accessibility_label prop matches matcher.
get_by_label
¶
Return the single view whose accessibility_label matches matcher; raise LookupError if not.
query_by_label
¶
Return the first view whose accessibility_label prop matches matcher, or None.
get_all_by_type
¶
Return every view of native type type_name (for example "Text").
get_by_type
¶
Return the single view of native type type_name; raise LookupError otherwise.
query_by_type
¶
Return the first view of native type type_name, or None.
fire
¶
Dispatch event (an on_* prop name) to target and settle.
Raises:
| Type | Description |
|---|---|
LookupError
|
If no handler is registered for the event. |
render
¶
render(
element: Node,
*,
viewport: Optional[
Tuple[float, float]
] = DEFAULT_VIEWPORT,
backend: Optional[FakeBackend] = None,
host: Optional[FakeHost] = None,
settle_first: bool = True
) -> RenderResult
Mount element into a FakeBackend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Node
|
The element (or component call) to render. |
required |
viewport
|
Optional[Tuple[float, float]]
|
Size for the layout pass; |
DEFAULT_VIEWPORT
|
backend
|
Optional[FakeBackend]
|
Reuse an existing backend (defaults to a fresh one). |
None
|
host
|
Optional[FakeHost]
|
Render under a |
None
|
settle_first
|
bool
|
Drain async work and effects before returning. |
True
|
Next steps¶
- Read the Testing guide for patterns.
- Test navigation flows against a
FakeHost.