{ "info": { "author": "Ordanis Sanchez", "author_email": "ordanisanchez@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: AsyncIO", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Testing" ], "description": "# asgi-testClient\n![Travis (.org)](https://img.shields.io/travis/oldani/asgi-testClient.svg)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/asgi-testClient.svg)\n![PyPI](https://img.shields.io/pypi/v/asgi-testClient.svg)\n[![codecov](https://codecov.io/gh/oldani/asgi-testClient/branch/master/graph/badge.svg)](https://codecov.io/gh/oldani/asgi-testClient)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/asgi-testClient.svg)\n[![black](https://img.shields.io/badge/code_style-black-000000.svg)](https://github.com/ambv/black)\n\nTesting ASGI applications made easy!\n\n\n## The why?\n\n**Why** would you build this when all web frameworks come with one? Well, because mostly all those web frameworks have to build their own. I was building my own web framework perhaps (research & learning purpose) and got to the point where a needed a `TestClient` but then a asked my self **why does anybody building web frameworks have to build their own TestClient when there's a standard?**. Ok, then just install `starlette` a use it test client; would you install a library just to use a tiny part of it? **This client does not have any dependencies**.\n\n## Requirements\n\n`Python 3.6+`\n\nIt should run on Python 3.5 but I haven' tested it.\n\n## Installation\n\n`pip install asgi-testclient`\n\n\n## Usage\n\nThe client replicates the requests API, so if you have used request you should feel comfortable. **Note:** the client method are coroutines `get, post, delete, put, patch, etc..`.\n\n```python\nimport pytest\nfrom asgi_testclient import TestClient\n\nfrom myapp import API\n\n@pytest.fixture\ndef client():\n return TestClient(API)\n\n@pytest.mark.asyncio\nasync def test_get(client):\n response = await client.get(\"/\")\n assert response.json() == {\"hello\": \"world\"}\n assert response.status_code == 200\n```\n\nI have used `pytest` in this example but you can use whichever runner you prefer.\n\nIf you still prefer simple functions to coroutines, you can use the sync interface:\n\n```python\nimport pytest\nfrom asgi_testclient.sync import TestClient\n\n@pytest.fixture\ndef client():\n return TestClient(API)\n\ndef test_get(client):\n response = client.get(\"/\")\n assert response.json() == {\"hello\": \"world\"}\n assert response.status_code == 200\n```\n\n**Take in account that if you're running inside an async app you should use the async client, yet you can run the sync one inside threads is still desired.**\n\n\n## Websockets\n\nIf you're using ASGI you may be doing some web-sockets stuff. We have added support for it also, so you can test it easy.\n\n```python\nfrom asgi_testclient import TestClient\nfrom myapp import API\n\nasync def test_send():\n echo_server = TestClient(API)\n websocket = await echo_server.ws_connect(\"/\")\n for msg in [\"Hey\", \"Echo\", \"Back\"]:\n await websocket.send_text(msg)\n data = await websocket.receive_text()\n assert data == msg\n await websocket.close()\n\nasync def test_ws_context():\n client = TestClient(API)\n async with client.ws_session(\"/\") as websocket:\n data = await websocket.receive_text()\n assert data == \"Hello, world!\"\n```\n\nFew things to take in count here:\n1. When using `ws_connect` you must call `websocket.close()` to finish up your APP task.\n2. For using websockets in context manager you must use `ws_session` instead of `ws_connect`.\n3. When waiting on server response `websocker.receive_*` it may raise a `WsDisconnect`.\n\nAnd one more time for those who don't want to this async we got the sync version:p\n\n```python\nfrom asgi_testclient.sync import TestClient\nfrom myapp import API\n\nclient = TestClient(API)\n\ndef test_send_receive_json():\n websocket = client.ws_connect(\"/json\")\n\n json_msg = {\"hello\": \"test\"}\n websocket.send_json(json_msg)\n\n assert websocket.receive_json() == json_msg\n websocket.close()\n\ndef test_ws_context():\n with client.ws_session(\"/\") as websocket:\n data = websocket.receive_text()\n assert data == \"Hello, world!\"\n```\n\n**Important:** In the sync version you cannot use `send` or `receive` since they're coroutines, instead use their children `send_*` or `receive_*` `text|bytes|json`.\n\nAlso sync version is done throw `monkey patching` so you can't use both version `async & sync` at the same time.\n\n## TODO:\n- [x] Support Websockets client.\n- [ ] Cookies support.\n- [ ] Redirects.\n- [ ] Support files encoding\n- [ ] Stream request & response\n\n\n## Credits\n\n- `Tom Christie`: I brought inspiration from the `starlette` test client.\n- `Kenneth \u2624 Reitz`: This package tries to replicate `requests` API.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/oldani/asgi-testClient", "keywords": "", "license": "MIT", "maintainer": "Ordanis Sanchez", "maintainer_email": "ordanisanchez@gmail.com", "name": "asgi-testclient", "package_url": "https://pypi.org/project/asgi-testclient/", "platform": "", "project_url": "https://pypi.org/project/asgi-testclient/", "project_urls": { "Homepage": "https://github.com/oldani/asgi-testClient", "Repository": "https://github.com/oldani/asgi-testClient" }, "release_url": "https://pypi.org/project/asgi-testclient/0.3.1/", "requires_dist": null, "requires_python": ">=3.6,<4.0", "summary": "Test Clietn for ASGI web applications", "version": "0.3.1" }, "last_serial": 5801264, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "87e2d23048bce043e90565e875ed7ac6", "sha256": "9de288dd57231db0d89e79da3dcda90b96fa88fd0abf623050540f4f0b0dad75" }, "downloads": -1, "filename": "asgi_testclient-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "87e2d23048bce043e90565e875ed7ac6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 13844, "upload_time": "2019-02-28T23:06:26", "url": "https://files.pythonhosted.org/packages/e7/77/c1176aaf27dd69d420c234f4d5a3a3661fbb60a6b4437a89b25f53226313/asgi_testclient-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ea974883bc6fdfc4466610dd77c381f9", "sha256": "164fa964433ed2ad0995029cc39ad1c5288672758f6af244f9175f5f2a62ac64" }, "downloads": -1, "filename": "asgi-testclient-0.1.0.tar.gz", "has_sig": false, "md5_digest": "ea974883bc6fdfc4466610dd77c381f9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 6024, "upload_time": "2019-02-28T23:06:24", "url": "https://files.pythonhosted.org/packages/ad/39/11491b238bb5746cf8053dcd23571d1b04f4333c3a274f64968e7d50a7b2/asgi-testclient-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "47b88ff5c7dc4d31bfbb48d922e62519", "sha256": "9c6bc476ff9079808dd16441926af9e946d28290df836a4b6c49e727322692a5" }, "downloads": -1, "filename": "asgi_testclient-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "47b88ff5c7dc4d31bfbb48d922e62519", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 15823, "upload_time": "2019-03-03T04:51:03", "url": "https://files.pythonhosted.org/packages/20/3c/f2a64e835bff59d37f02895bc75456ff472381b8d08438a0ac87ed203975/asgi_testclient-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "afb8b257d6e8d633965ebe68163f1c9b", "sha256": "d524ce2df9a5447859bdf262243336939145a5e8c2497c263be09431154f9f5e" }, "downloads": -1, "filename": "asgi-testclient-0.2.0.tar.gz", "has_sig": false, "md5_digest": "afb8b257d6e8d633965ebe68163f1c9b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 6476, "upload_time": "2019-03-03T04:51:01", "url": "https://files.pythonhosted.org/packages/6f/5d/69284d6cb0a8588ae098983d01b6d9e5f69005043c255c0de84a9087a83e/asgi-testclient-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "6bdcd4882e3b819d635af6c9f80c0058", "sha256": "474a405167728b5fdd87513c4be7031930fe920c30b82280a9fe74172910f3b2" }, "downloads": -1, "filename": "asgi_testclient-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "6bdcd4882e3b819d635af6c9f80c0058", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 21680, "upload_time": "2019-03-05T12:16:40", "url": "https://files.pythonhosted.org/packages/18/c8/0c93d6dc4818ac4073db9c7587166529d0887a143570d50cb97555767267/asgi_testclient-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d4c85a8153f1010374036daa9c275e11", "sha256": "b15a16c09d2c2c7a8eb4c6173af059a77e3e92574e2972261433bb6ac19f249b" }, "downloads": -1, "filename": "asgi-testclient-0.3.0.tar.gz", "has_sig": false, "md5_digest": "d4c85a8153f1010374036daa9c275e11", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8208, "upload_time": "2019-03-05T12:16:39", "url": "https://files.pythonhosted.org/packages/33/1a/0b8e3bb817bb25ae15251a995d0f0326449733a1157ea10e576b99742afe/asgi-testclient-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "5b22ad1f4c42aa810431541383e7b0f5", "sha256": "279ff81a26330a3b234c55c2fba016e8bad1732f89e217263034872c12873c80" }, "downloads": -1, "filename": "asgi_testclient-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5b22ad1f4c42aa810431541383e7b0f5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 9120, "upload_time": "2019-09-09T01:33:49", "url": "https://files.pythonhosted.org/packages/c7/83/77795a0782ca3f7b9ba586187a5626ebd044ca64120a02d1490f0b2d44c3/asgi_testclient-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1f30eeceff4104df85961bf38e91141c", "sha256": "f9fc014604e751978562aaf8fbd72f4d9c140340233f119c0f96894efd9504fc" }, "downloads": -1, "filename": "asgi-testclient-0.3.1.tar.gz", "has_sig": false, "md5_digest": "1f30eeceff4104df85961bf38e91141c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 9892, "upload_time": "2019-09-09T01:33:47", "url": "https://files.pythonhosted.org/packages/9b/fb/5e1587fa559d8b083e1b271c33205ae8d5c6740a21e394801a64f2d01473/asgi-testclient-0.3.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5b22ad1f4c42aa810431541383e7b0f5", "sha256": "279ff81a26330a3b234c55c2fba016e8bad1732f89e217263034872c12873c80" }, "downloads": -1, "filename": "asgi_testclient-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5b22ad1f4c42aa810431541383e7b0f5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 9120, "upload_time": "2019-09-09T01:33:49", "url": "https://files.pythonhosted.org/packages/c7/83/77795a0782ca3f7b9ba586187a5626ebd044ca64120a02d1490f0b2d44c3/asgi_testclient-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1f30eeceff4104df85961bf38e91141c", "sha256": "f9fc014604e751978562aaf8fbd72f4d9c140340233f119c0f96894efd9504fc" }, "downloads": -1, "filename": "asgi-testclient-0.3.1.tar.gz", "has_sig": false, "md5_digest": "1f30eeceff4104df85961bf38e91141c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 9892, "upload_time": "2019-09-09T01:33:47", "url": "https://files.pythonhosted.org/packages/9b/fb/5e1587fa559d8b083e1b271c33205ae8d5c6740a21e394801a64f2d01473/asgi-testclient-0.3.1.tar.gz" } ] }