使用 PyTest 进行测试时如何在后台启动 Uvicorn + FastAPI [英] How to start a Uvicorn + FastAPI in background when testing with PyTest

查看:98
本文介绍了使用 PyTest 进行测试时如何在后台启动 Uvicorn + FastAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 Uvicorn+FastAPI

我想使用 PyTest 进行测试.

Which I want to test using PyTest.

我想在开始测试时在夹具中启动服务器,所以当测试完成时,夹具将终止应用程序.

I want to start the server in a fixture when I start the tests, so when the test complete, the fixture will kill the app.

FastAPI 测试展示了如何测试 API 应用,

FastAPI Testing shows how to test the API app,

from fastapi import FastAPI
from starlette.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"}

这不会以通常的方式使服务器联机.看来,client.get 命令触发的特定功能是唯一运行的东西.

This doesn't bring the server online in the usual way. It seems that the specific functionality that is triggered by the client.get command is the only thing that runs.

我找到了这些额外的资源,但我无法让它们为我工作:

I found these additional resources, but I can't make them work for me:

https://medium.com/@hmajid2301/pytest-with-background-thread-fixtures-f0dc34ee3c46

如何将服务器作为 py.test 的夹具运行

您将如何从 PyTest 运行 Uvicorn+FastAPI 应用程序,以便它随着测试而上升和下降?

推荐答案

灵感来自 @Gabriel C 的答案.完全面向对象的异步方法(使用出色的 asynctest 框架).

Inspired from @Gabriel C answer. A fully object oriented and async approach (using the excellent asynctest framework).

import logging
from fastapi import FastAPI

class App:
    """ Core application to test. """

    def __init__(self):
        self.api = FastAPI()
        # register endpoints
        self.api.get("/")(self.read_root)
        self.api.on_event("shutdown")(self.close)

    async def close(self):
        """ Gracefull shutdown. """
        logging.warning("Shutting down the app.")

    async def read_root(self):
        """ Read the root. """
        return {"Hello": "World"}

""" Testing part."""
from multiprocessing import Process
import asynctest
import asyncio
import aiohttp
import uvicorn

class TestApp(asynctest.TestCase):
    """ Test the app class. """

    async def setUp(self):
        """ Bring server up. """
        app = App()
        self.proc = Process(target=uvicorn.run,
                            args=(app.api,),
                            kwargs={
                                "host": "127.0.0.1",
                                "port": 5000,
                                "log_level": "info"},
                            daemon=True)
        self.proc.start()
        await asyncio.sleep(0.1)  # time for the server to start

    async def tearDown(self):
        """ Shutdown the app. """
        self.proc.terminate()

    async def test_read_root(self):
        """ Fetch an endpoint from the app. """
        async with aiohttp.ClientSession() as session:
            async with session.get("http://127.0.0.1:5000/") as resp:
                data = await resp.json()
        self.assertEqual(data, {"Hello": "World"})

这篇关于使用 PyTest 进行测试时如何在后台启动 Uvicorn + FastAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆