nvda-addon-testkit
Project board — live roadmap and status for this repo's issues.
End-to-end testing for NVDA add-ons, against a real NVDA, in CI.
Your add-on's logic can be unit-tested with stubs. What cannot be stubbed is whether it installs, registers, and behaves inside NVDA itself. This kit provisions a disposable portable NVDA, installs your add-on into it, and lets pytest drive it.
def test_my_addon_announces_itself(nvda, addon_under_test):
before = nvda.speech.index()
nvda.keys.press("NVDA+shift+m")
assert "my add-on is ready" in nvda.speech.wait_for("ready", timeout=10, since=before).text
nvda.log.assert_no_errors()
Install
pip install nvda-addon-testkit
Configure
[tool.nvda-testkit]
addon-bundle = "dist/my-addon-*.nvda-addon"
nvda-channel = "stable"
Run in GitHub Actions
jobs:
e2e:
runs-on: windows-2025
steps:
- uses: actions/checkout@v5
- uses: zirekhq/nvda-addon-testkit@v1
with:
nvda-channel: stable
- run: pytest tests_e2e/ -v
The action is OS-agnostic — pick whichever Windows runner matches what
your users run. This repository's e2e test suite runs on both windows-2025
and windows-2022 (the latter for Windows 10 22H2, including builds
still on Extended Security Updates).
What you get
| Fixture | What it gives you |
|---|---|
nvda |
a connected client, reset between tests |
addon_bundle |
the path to your built .nvda-addon |
addon_under_test |
that bundle, installed and enabled, NVDA restarted |
| Namespace | Use it for |
|---|---|
nvda.speech |
what NVDA asked to say, and waiting for it |
nvda.braille |
the raw text sent to the braille display |
nvda.keys |
sending gestures through NVDA's own input pipeline |
nvda.config |
reading and writing NVDA's configuration |
nvda.log |
structured log records, and assert_no_errors() |
nvda.addons |
two-phase install, remove, and state |
nvda.eval() runs a single expression inside NVDA; nvda.exec() runs a
full multi-statement scenario and returns whatever it binds to
__result__. Both need --nvda-allow-eval. A bad scenario raises
ScenarioSyntaxError, so catching bare except Exception: pass around
either call still swallows it — catch the types you expect instead.
nvda.restart_harness() kills and relaunches the NVDA process — use it to
finish a two-phase add-on install or reset to a clean process. It does not
exercise NVDA's own restart logic. For that, use nvda.restart_nvda(),
which triggers NVDA's real core.restart() and waits for the replacement
process — needs --nvda-allow-eval, since it is built on nvda.eval().
Requirements
Windows to run the tests. NVDA is downloaded automatically — you do not need one installed, and nothing touches an NVDA you already have.
Tests run serially: only one NVDA can own a desktop session, so pytest-xdist with more than one worker is refused rather than silently producing nonsense.
Developing the kit itself
The host side is fully testable on Linux against a scriptable double:
pip install -e ".[dev]"
python tools/build_spy.py
pytest # host and spy unit tests, any platform
pytest tests_e2e/ -v # real NVDA, Windows only
nvda-testkit doctor # check this machine
Licence
GPL-2.0-or-later.
💝 Support This Project
If this repository saves you time and effort, please consider supporting it!
- ⭐ Star on GitHub
- 🐦 Share on Twitter
- 💖 More ways to support — Open Collective coming soon
Metadata
Release files for nvda-addon-testkit 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nvda_addon_testkit-1.0.0.tar.gz | 175.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nvda_addon_testkit-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 223.1 kB
Release files / nvda_addon_testkit-1.0.0.tar.gz
| Download URL | nvda_addon_testkit-1.0.0.tar.gz |
|---|---|
| Size | 175.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b8bc1bf619503f68375611c81d2d3f6b1e5aaa69b1b954ba70c9c40dec4f921
|
|
BLAKE2b-256 checksum How to use checksums |
59b71a5bc12b08783a526000a80bf88d697bcf4d2d9213ba2d7acecd3f784a87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / nvda_addon_testkit-1.0.0-py3-none-any.whl
| Download URL | nvda_addon_testkit-1.0.0-py3-none-any.whl |
|---|---|
| Size | 47.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dfe60ca002eb4956e405af67427c8d3616371428874048d3f633c1830db96c11
|
|
BLAKE2b-256 checksum How to use checksums |
1d9ee22c137a02c1b6d86102300af30c1dc385f437cccdb5f95c4db5970e1f23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|