Fixtures

Fixture What it gives you

nvda

a connected client, reset between tests

addon_bundle

the path to your built .nvda-addon, resolved from addon-bundle in Installation

addon_under_test

that bundle, installed and enabled, NVDA restarted

nvda_settings

the session’s resolved TestkitSettings (see Installation)

nvda_session

the session-scoped NvdaClient behind nvda; see The client

addon_under_test is session-scoped: every test that asks for it shares the same installed add-on and the same running NVDA. The plain nvda fixture resets state between tests, so most tests only need nvda and addon_under_test together:

def test_it_survives_a_restart(nvda, addon_under_test):
    nvda.restart_harness()
    assert nvda.addons.state("testkit-demo") is AddonState.ENABLED
    before = nvda.speech.index()
    nvda.keys.press("NVDA+shift+control+d")
    nvda.speech.wait_for(SPOKEN_PHRASE, timeout=20, since=before)

Owning the install lifecycle

Reach for the raw nvda.addons namespace instead of addon_under_test when a test needs to drive install/remove itself — for example, to prove the two-phase install contract. Mark it @pytest.mark.fresh_nvda so it gets its own NVDA process rather than the shared session one:

built_demo_addon and assert_no_unexpected_errors are fixtures defined in this repository’s tests_e2e/conftest.py, not shipped by the plugin. Define your own equivalents (a fixture that builds your bundle, and one that calls nvda.log.assert_no_errors() after filtering the runner-environment errors your CI host produces), or drop them.

@pytest.mark.fresh_nvda
def test_install_is_two_phase_and_completes_on_restart(
    nvda, built_demo_addon, assert_no_unexpected_errors
):
    assert nvda.addons.state("testkit-demo") is AddonState.NOT_INSTALLED

    info = nvda.addons.install(built_demo_addon)
    assert info.name == "testkit-demo"
    assert nvda.addons.state("testkit-demo") is AddonState.PENDING_INSTALL

    nvda.restart_harness()
    assert nvda.addons.state("testkit-demo") is AddonState.ENABLED
    assert_no_unexpected_errors(nvda)

    nvda.addons.remove("testkit-demo")
    nvda.restart_harness()
    assert nvda.addons.state("testkit-demo") is AddonState.NOT_INSTALLED

See nvda.addons for what each AddonState means.