Reputation: 1498
I am trying to have working tests for an API written with FastAPI.
I start the service in a separate process, run the tests with requests to the service, and check if the results are as expected.
I have extracted the key parts into a minimal working example, in the PD.
Running the MWE with the main file works fine. The tests fail, though.
PD: the code is in a GIST, but now also here:
# Minimal example to ask in StackOverflow
Pytest does not allow to start a process with a service and tests requests to it,
at least not in the most straightforward way IMHO.
I may be missing something, or I may be doing something wrong.
Hence, I share this short code in a gist, to ask.
## How to run it
The dependencies are: `fastapi pytest requests uvicorn`.
You may install them with your package / environment manager of choice,
or use `pipenv install` with the provided `Pipfile`.
To run the code in the environment (e.g. `pipenv shell`), run: `python3 mwe.py`.
You should see everything is `OK`.
To run the test, run in the environment: `pytest`.
This does not work for me, the request times out.
import fastapi, multiprocessing, requests, time, uvicorn
app = fastapi.FastAPI()
@app.get('/ok')
def ok():
return 'OK'
class service:
def __enter__(self):
def run_service():
uvicorn.run('mwe:app', host='0.0.0.0', port=8000, reload=True)
self.service = multiprocessing.Process(target=run_service)
self.service.start()
time.sleep(10)
def __exit__(self, *args):
self.service.terminate()
def main():
with service():
return requests.get('http://127.0.0.1:8000/ok').ok
if __name__ == '__main__':
print('🆖🆗'[main()])
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pytest = "*"
fastapi = "*"
requests = "*"
uvicorn = "*"
[requires]
python_version = "3.10"
python_full_version = "3.10.6"
from mwe import main
def test_main():
assert main()
Upvotes: 0
Views: 788
Reputation: 533
Example for testing from official docs
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/")
async def read_main():
return {"msg": "Hello World"}
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"msg": "Hello World"}
So, for you example from attached git it can be rewrited to something like this:
def test_get_ok():
response = client.get("/ok")
assert response.status_code == 200
assert response.text() == 'OK'
In a nutshell, it is difficult to describe how to test API correctly, but you can take as an example an excellent template for designing RESTfull API on FastAPI in which there are examples of autotests written just with the Pytest
Upvotes: 1