You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI独立进程pytest测试失败排查及API测试方案咨询

FastAPI API测试问题求助

我正在为FastAPI编写API测试,通过独立进程启动服务,用requests发请求验证结果。提取关键代码做成最小复现示例后,直接运行主文件一切正常,但执行pytest测试时请求超时失败。想请教:

  1. 测试失败的原因是什么?
  2. 正确的API测试方式应该是怎样的?

代码详情

README.md

# 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.

mwe.py

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()])

Pipfile

[[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"

test_mwe.py

from mwe import main

def test_main():
    assert main()

问题解答

1. 测试失败的原因

  • reload=True的多进程干扰:uvicorn的热重载模式会启动额外子进程监控文件变化,在pytest的进程环境中,这种嵌套进程会导致服务无法正常初始化,最终服务未真正启动,请求超时。
  • 固定等待不可靠:time.sleep(10)是固定时长等待,无法确保服务完成启动,测试环境中资源调度可能更慢,导致等待时间不足。
  • 进程环境冲突:pytest运行测试时的进程上下文,可能导致multiprocessing.Process启动的服务进程无法正确加载应用实例或监听端口。

2. 正确的API测试方式

FastAPI官方推荐两种测试方式,根据需求选择:

方案一:使用TestClient(推荐)

无需启动真实HTTP服务,直接通过TestClient模拟请求,测试效率更高、更稳定,这是FastAPI的标准测试方案。

修改后的核心代码:

# mwe.py
import fastapi, requests, uvicorn
from httpx import TestClient

app = fastapi.FastAPI()

@app.get('/ok')
def ok():
    return 'OK'

# 创建TestClient实例
client = TestClient(app)

def main():
    # 本地运行时用真实请求,测试环境用TestClient
    try:
        return requests.get('http://127.0.0.1:8000/ok').ok
    except requests.exceptions.ConnectionError:
        response = client.get('/ok')
        return response.status_code == 200

# 保留原有的服务启动逻辑用于本地运行
class Service:
    def __enter__(self):
        def run_service():
            # 关闭热重载避免多进程问题
            uvicorn.run('mwe:app', host='0.0.0.0', port=8000, reload=False)
        import multiprocessing
        self.service = multiprocessing.Process(target=run_service)
        self.service.start()
        # 用端口轮询替代固定等待,确保服务启动
        import time
        import socket
        def wait_for_port(port, timeout=30):
            start_time = time.time()
            while time.time() - start_time < timeout:
                try:
                    with socket.create_connection(('127.0.0.1', port), timeout=1):
                        return True
                except (ConnectionRefusedError, socket.timeout):
                    time.sleep(0.5)
            return False
        wait_for_port(8000)

    def __exit__(self, *args):
        self.service.terminate()

if __name__ == '__main__':
    with Service():
        print('🆖🆗'[main()])

测试代码简化为:

# test_mwe.py
from mwe import client

def test_ok_endpoint():
    response = client.get('/ok')
    assert response.status_code == 200
    assert response.text == '"OK"'

方案二:修复真实服务启动逻辑

如果必须启动真实HTTP服务测试,需要调整以下几点:

  • 关闭uvicorn的reload模式(设为reload=False),避免多进程嵌套。
  • 用端口轮询替换time.sleep,确保服务真正启动后再发请求。
  • 确保测试结束后正确终止服务进程,避免端口残留。

修改后的service类可参考方案一中的Service类,测试代码保持原有的test_main即可。


内容的提问来源于stack exchange,提问作者Trylks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:35:42