{"id":20289139,"url":"https://github.com/oldani/asgi-testclient","last_synced_at":"2025-04-11T10:14:06.374Z","repository":{"id":34243272,"uuid":"172812198","full_name":"oldani/asgi-testClient","owner":"oldani","description":"Testing ASGI applications made easy!","archived":false,"fork":false,"pushed_at":"2022-08-09T15:20:04.000Z","size":45,"stargazers_count":11,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T07:01:37.395Z","etag":null,"topics":["asgi","asyncio","testing","testing-tools","webframework"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oldani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-27T00:23:18.000Z","updated_at":"2022-06-28T19:00:29.000Z","dependencies_parsed_at":"2022-08-27T17:10:43.929Z","dependency_job_id":null,"html_url":"https://github.com/oldani/asgi-testClient","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldani%2Fasgi-testClient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldani%2Fasgi-testClient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldani%2Fasgi-testClient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oldani%2Fasgi-testClient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oldani","download_url":"https://codeload.github.com/oldani/asgi-testClient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248373066,"owners_count":21093138,"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":["asgi","asyncio","testing","testing-tools","webframework"],"created_at":"2024-11-14T14:50:20.575Z","updated_at":"2025-04-11T10:14:06.358Z","avatar_url":"https://github.com/oldani.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# asgi-testClient\n[![Build Status](https://travis-ci.org/oldani/asgi-testClient.svg?branch=master)](https://travis-ci.org/oldani/asgi-testClient)\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 \u0026 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 \u0026 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 \u0026 response\n\n\n## Credits\n\n- `Tom Christie`: I brought inspiration from the `starlette` test client.\n- `Kenneth ☤ Reitz`: This package tries to replicate `requests` API.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foldani%2Fasgi-testclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foldani%2Fasgi-testclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foldani%2Fasgi-testclient/lists"}