{"ok": true, "next": null, "rows": [{"id": "testing_plugins:id1", "page": "testing_plugins", "ref": "id1", "title": "Testing plugins", "content": "We recommend using  pytest  to write automated tests for your plugins. \n         If you use the template described in  Starting an installable plugin using cookiecutter  your plugin will start with a single test in your  tests/  directory that looks like this: \n         from datasette.app import Datasette\nimport pytest\n\n\n@pytest.mark.asyncio\nasync def test_plugin_is_installed():\n    datasette = Datasette(memory=True)\n    response = await datasette.client.get(\"/-/plugins.json\")\n    assert response.status_code == 200\n    installed_plugins = {p[\"name\"] for p in response.json()}\n    assert (\n        \"datasette-plugin-template-demo\"\n        in installed_plugins\n    ) \n         This test uses the  datasette.client  object to exercise a test instance of Datasette.  datasette.client  is a wrapper around the  HTTPX  Python library which can imitate HTTP requests using ASGI. This is the recommended way to write tests against a Datasette instance. \n         This test also uses the  pytest-asyncio  package to add support for  async def  test functions running under pytest. \n         You can install these packages like so: \n         pip install pytest pytest-asyncio \n         If you are building an installable package you can add them as test dependencies to your  pyproject.toml  file like this: \n         [project]\nname = \"datasette-my-plugin\"\n# ...\n\n[project.optional-dependencies]\ntest = [\"pytest\", \"pytest-asyncio\"] \n         You can then install the test dependencies like so: \n         pip install -e '.[test]' \n         Then run the tests using pytest like so: \n         pytest", "breadcrumbs": "[]", "references": "[{\"href\": \"https://docs.pytest.org/\", \"label\": \"pytest\"}, {\"href\": \"https://www.python-httpx.org/\", \"label\": \"HTTPX\"}, {\"href\": \"https://pypi.org/project/pytest-asyncio/\", \"label\": \"pytest-asyncio\"}]"}], "truncated": false}