Testing Widgets

A widget renders to a canvas and handles keys and mouse events through plain method calls, so a test needs no terminal. The urwid.testing module collects the helpers such tests keep rewriting. It is not imported by urwid, so the examples below start with:

from urwid.testing import ScriptedScreen, check_sizing, press, render_runs, render_text

Every check raises AssertionError with a message that names the call and the mismatch, and the module imports no test framework, so the helpers work with unittest, pytest or any other runner.

Rendering

render_text() renders a widget and returns its rows as text, and render_runs() returns each row as (attr, text) runs:

>>> from urwid import Text
>>> render_text(Text("ab cd"), (3,))
['ab ', 'cd ']
>>> render_runs(Text([("bold", "Hi"), "!"]), (3,))
[[('bold', 'Hi'), (None, '!')]]

resolve_attr() and resolve_runs() show the colors a screen with a given palette draws those attributes with.

Sizing checks

check_sizing() renders a widget at the degenerate and full sizes of each of its sizing modes, with focus off and on, and checks that the canvas has the size the widget promised and a cursor inside it:

>>> from urwid import Pile
>>> check_sizing(Pile([Text("x")]))

The checks empty the canvas cache before every case, so they belong in tests, not in a running application.

Input

press() sends keys and returns the ones the widget did not handle; click() sends one mouse event with named arguments:

>>> from urwid import Edit
>>> press(Edit("> "), (10,), "a", "b", "esc")
['esc']

Whole applications

ScriptedScreen stands in for the terminal of a MainLoop. It returns a fixed screen size, feeds scripted batches of input, stops the loop once they are used up, and records every distinct frame drawn:

>>> from urwid import Filler, MainLoop
>>> screen = ScriptedScreen(size=(6, 1), inputs=[["a", "b"], ["backspace"]])
>>> MainLoop(Filler(Edit("> ")), screen=screen).run()
>>> screen.last_text
['> a   ']

To keep the frames as HTML for documentation instead, use urwid.display.html_fragment.HtmlGenerator.