{"id":15017332,"url":"https://github.com/glutanimate/pytest-anki","last_synced_at":"2025-04-12T11:43:13.993Z","repository":{"id":36980668,"uuid":"228679225","full_name":"glutanimate/pytest-anki","owner":"glutanimate","description":"A pytest plugin for testing Anki add-ons","archived":false,"fork":false,"pushed_at":"2025-04-09T22:05:11.000Z","size":314,"stargazers_count":28,"open_issues_count":7,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-09T22:38:43.587Z","etag":null,"topics":["anki","anki-addon","e2e-testing","pyqt5","pytest","pytest-plugin","python","test-automation","ui-testing"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pytest-anki/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/glutanimate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"patreon":"glutanimate","ko_fi":"glutanimate"}},"created_at":"2019-12-17T18:37:39.000Z","updated_at":"2025-01-05T19:49:14.000Z","dependencies_parsed_at":"2023-02-10T04:31:30.275Z","dependency_job_id":"b69fd09c-48db-405a-ad5a-e6d6a3b1579a","html_url":"https://github.com/glutanimate/pytest-anki","commit_stats":{"total_commits":362,"total_committers":4,"mean_commits":90.5,"dds":0.06906077348066297,"last_synced_commit":"02f83a223f17689fddca4e4ce3f5387361af42c5"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glutanimate%2Fpytest-anki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glutanimate%2Fpytest-anki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glutanimate%2Fpytest-anki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glutanimate%2Fpytest-anki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/glutanimate","download_url":"https://codeload.github.com/glutanimate/pytest-anki/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248564030,"owners_count":21125404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anki","anki-addon","e2e-testing","pyqt5","pytest","pytest-plugin","python","test-automation","ui-testing"],"created_at":"2024-09-24T19:50:19.051Z","updated_at":"2025-04-12T11:43:13.967Z","avatar_url":"https://github.com/glutanimate.png","language":"Python","funding_links":["https://patreon.com/glutanimate","https://ko-fi.com/glutanimate"],"categories":[],"sub_categories":[],"readme":"# pytest-anki\n\npytest-anki is a [pytest](https://docs.pytest.org/) plugin that allows developers to write tests for their [Anki add-ons](https://addon-docs.ankiweb.net/).\n\nAt its core lies the `anki_session` fixture that provides add-on authors with the ability to create and control headless Anki sessions to test their add-ons in:\n\n```python\nfrom pytest_anki import AnkiSession\n\ndef test_addon_registers_deck(anki_session: AnkiSession):\n    my_addon = anki_session.load_addon(\"my_addon\")\n    with anki_session.load_profile()\n        with anki_session.deck_installed(deck_path) as deck_id:\n            assert deck_id in my_addon.deck_ids\n\n```\n\n`anki_session` comes with a comprehensive API that allows developers to programmatically manipulate Anki, set up and reproduce specific configurations, simulate user interactions, and much more.\n\nThe goal is to provide add-on authors with a one-stop-shop for their functional testing needs, while also enabling them to QA their add-ons against a battery of different Anki versions, catching incompatibilities as they arise.\n\n![PyPI](https://img.shields.io/pypi/v/pytest-anki) \u003ca title=\"License: GNU AGPLv3\" href=\"https://github.com/glutanimate/anki-addon-builder/blob/master/LICENSE\"\u003e\u003cimg  src=\"https://img.shields.io/badge/license-GNU AGPLv3-f37f40.svg\"\u003e\u003c/a\u003e  \u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"\u003e\u003c/a\u003e  [![tests](https://github.com/glutanimate/pytest-anki/actions/workflows/general.yml/badge.svg)](https://github.com/glutanimate/pytest-anki/actions/workflows/general.yml) \n\n## Disclaimer\n\n### Project State\n\n**Important**: The plugin is currently undergoing a major rewrite and expansion of its feature-set, so the documentation below is very sparse at the moment. I am working on bringing the docs up to speed, but until then, please feel free to check out the inline documentation and also take a look at the plug-in's tests for a number of hopefully helpful examples.\n\n### Platform Support\n\n`pytest-anki` has only been confirmed to work on Linux so far.\n\n\n## Installation\n\n### Requirements\n\n`pytest-anki` requires Python 3.8+.\n\n### Installing the latest packaged build\n\n```bash\n$ pip install pytest-anki\n```\n\nor\n\n```bash\n$ poetry add --dev pytest-anki\n```\n\n\n## Usage\n\n### Basic Use\n\nIn your tests add:\n   \n```python\nfrom pytest_anki import AnkiSession  # for type checking and completions\n\n@pytest.mark.forked\ndef test_my_addon(anki_session: AnkiSession):\n    # add some tests in here\n```\n\nThe `anki_session` fixture yields an `AnkiSession` object that gives you access to the following attributes, among others:\n\n```\napp {AnkiApp} -- Anki QApplication instance\nmw {AnkiQt} -- Anki QMainWindow instance\nuser {str} -- User profile name (e.g. \"User 1\")\nbase {str} -- Path to Anki base directory\n```\n\nAdditionally, the fixture provides a number of helpful methods and context managers, e.g. for initializing an Anki profile:\n\n```python\n@pytest.mark.forked\ndef test_my_addon(anki_session: AnkiSession):\n    with anki_session.profile_loaded():\n        assert anki_session.collection\n```\n\n\n### Configuring the Anki Session\n\nYou can customize the Anki session context by passing arguments to the `anki_session` fixture using pytest's indirect parametrization, e.g.\n\n```python\nimport pytest\n\n@pytest.mark.forked\n@pytest.mark.parametrize(\"anki_session\", [dict(load_profile=True)], indirect=True)\ndef test_my_addon(anki_session: AnkiSession):\n    # profile / collection already pre-loaded!\n    assert anki_session.collection\n```\n\n## Additional Notes\n\n### When to use pytest-anki\n\nRunning your test in an Anki environment is expensive and introduces an additional layer of confounding factors. If you can `mock` your Anki runtime dependencies away, then that should always be your first tool of choice.\n\nWhere `anki_session` comes in handy is further towards the upper levels of the test pyramid, i.e. functional tests, end-to-end tests, and UI tests. Additionally the plugin can provide you with a convenient way to automate testing for incompatibilities with Anki and other add-ons.\n\n### The importance of forking your tests\n\nYou might have noticed that most of the examples above use a `@pytest.mark.forked` decorator. This is because, while the plugin does attempt to tear down Anki sessions as cleanly as possible on exit, this process is never quite perfect, especially for add-ons that monkey-patch Anki.\n\nWith unforked test runs, factors like that can lead to unexpected behavior, or worse still, your tests crashing. Forking a new subprocess for each test bypasses these limitations, and therefore my advice would be to mark any `anki_session` tests as forked by default.\n\nTo do this in batch for an entire test module, you can use the following pytest hook:\n\n```python\ndef pytest_collection_modifyitems(items):\n    for item in items:\n        item.add_marker(\"forked\")\n```\n\nFuture versions of `pytest-anki` will possibly do this by default.\n\n### Automated Testing\n\n`pytest-anki` is designed to work well with continuous integration systems such as GitHub actions. For an example see `pytest-anki`'s own [GitHub workflows](./.github/workflows/).\n\n\n### Troubleshooting\n\n#### pytest hanging when using xvfb\n\nEspecially if you run your tests headlessly with `xvfb`, you might run into cases where pytest will sometimes appear to hang. Oftentimes this is due to blocking non-dismissable prompts that your add-on code might invoke in some scenarios. If you suspect that might be the case, my advice would be to temporarily bypass `xvfb` locally via `pytest --no-xvfb` to show the UI and manually debug the issue.\n\n## Contributing\n\nContributions are welcome! To set up `pytest-anki` for development, please first make sure you have Python 3.8+ and [poetry](https://python-poetry.org/docs/) installed, then run the following steps:\n\n```\n$ git clone https://github.com/glutanimate/pytest-anki.git\n\n$ cd pytest-anki\n\n# Either set up a new Python virtual environment at this stage\n# (e.g. using pyenv), or let poetry create the venv for you\n\n$ make install\n```\n\nBefore submitting any changes, please make sure that `pytest-anki`'s checks and tests pass:\n\n```bash\nmake check\nmake lint\nmake test\n```\n\nThis project uses `black`, `isort` and `autoflake` to enforce a consistent code style. To auto-format your code you can use:\n\n```bash\nmake format\n```\n\n## License and Credits\n\n*pytest-anki* is\n\n*Copyright © 2019-2021 [Aristotelis P.](https://glutanimate.com/contact/) (Glutanimate) and [contributors](./CONTRIBUTORS)*\n\n*Copyright © 2017-2019 [Michal Krassowski](https://github.com/krassowski/anki_testing)*\n\n*Copyright © 2017-2021 [Ankitects Pty Ltd and contributors](https://github.com/ankitects/)*\n\n\nAll credits for the original idea for creating a context manager to test Anki add-ons with go to Michal. _pytest-anki_ would not exist without his [anki_testing](https://github.com/krassowski/anki_testing) project.\n\nI would also like to extend a heartfelt thanks to [AMBOSS](https://github.com/amboss-mededu/) for their major part in supporting the development of this plugin! Most of the recent feature additions leading up to v1.0.0 of the plugin were implemented as part of my work on the [AMBOSS add-on](https://www.amboss.com/us/anki-amboss).\n\n_pytest-anki_ is free and open-source software. Its source-code is released under the GNU AGPLv3 license, extended by a number of additional terms. For more information please see the [license file](https://github.com/glutanimate/pytest-anki/blob/master/LICENSE) that accompanies this program.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Please see the license file for more details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglutanimate%2Fpytest-anki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglutanimate%2Fpytest-anki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglutanimate%2Fpytest-anki/lists"}