Files
fastapi/docs/zh/docs/tutorial/testing.md
Motov Yurii eada361fa2 🌐 Update translations for zh (update-all) (#14917)
* Update all

* 🎨 Auto format

* Add missing

* 🎨 Auto format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-13 14:37:57 +01:00

192 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试 { #testing }
感谢 <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>,测试**FastAPI** 应用轻松又愉快。
它基于 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> 而HTTPX又是基于Requests设计的所以很相似且易懂。
有了它,你可以直接与**FastAPI**一起使用 <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a>。
## 使用 `TestClient` { #using-testclient }
/// info | 信息
要使用 `TestClient`,先要安装 <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>。
确保你创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装,例如:
```console
$ pip install httpx
```
///
导入 `TestClient`
通过传入你的**FastAPI**应用创建一个 `TestClient`
创建名字以 `test_` 开头的函数(这是标准的 `pytest` 约定)。
像使用 `httpx` 那样使用 `TestClient` 对象。
为你需要检查的地方用标准的Python表达式写个简单的 `assert` 语句(重申,标准的`pytest`)。
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
/// tip | 提示
注意测试函数是普通的 `def`,不是 `async def`
还有client的调用也是普通的调用不是用 `await`
这让你可以直接使用 `pytest` 而不会遇到麻烦。
///
/// note | 技术细节
你也可以用 `from starlette.testclient import TestClient`
**FastAPI** 提供了和 `starlette.testclient` 一样的 `fastapi.testclient`只是为了方便开发者。但它直接来自Starlette。
///
/// tip | 提示
除了发送请求之外如果你还想测试时在FastAPI应用中调用 `async` 函数(例如异步数据库函数), 可以在高级教程中看下 [Async Tests](../advanced/async-tests.md){.internal-link target=_blank} 。
///
## 分离测试 { #separating-tests }
在实际应用中,你可能会把你的测试放在另一个文件里。
您的**FastAPI**应用程序也可能由一些文件/模块组成等等。
### **FastAPI** app 文件 { #fastapi-app-file }
假设你有一个像 [更大的应用](bigger-applications.md){.internal-link target=_blank} 中所描述的文件结构:
```
.
├── app
│   ├── __init__.py
│   └── main.py
```
`main.py` 文件中你有一个 **FastAPI** app:
{* ../../docs_src/app_testing/app_a_py310/main.py *}
### 测试文件 { #testing-file }
然后你会有一个包含测试的文件 `test_main.py` 。app可以像Python包那样存在一样是目录但有个 `__init__.py` 文件):
``` hl_lines="5"
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```
因为这文件在同一个包中,所以你可以通过相对导入从 `main` 模块(`main.py`)导入`app`对象:
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
...然后测试代码和之前一样的。
## 测试:扩展示例 { #testing-extended-example }
现在让我们扩展这个例子,并添加更多细节,看下如何测试不同部分。
### 扩展后的 **FastAPI** app 文件 { #extended-fastapi-app-file }
让我们继续之前的文件结构:
```
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```
假设现在包含**FastAPI** app的文件 `main.py` 有些其他**路径操作**。
有个 `GET` 操作会返回错误。
有个 `POST` 操作会返回一些错误。
所有*路径操作* 都需要一个`X-Token` 头。
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
### 扩展后的测试文件 { #extended-testing-file }
然后您可以使用扩展后的测试更新`test_main.py`
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
每当你需要客户端在请求中传递信息,但你不知道如何传递时,你可以通过搜索(谷歌)如何用 `httpx`做,或者是用 `requests` 做毕竟HTTPX的设计是基于Requests的设计的。
接着只需在测试中同样操作。
示例:
* 传一个*路径* 或*查询* 参数添加到URL上。
* 传一个JSON体传一个Python对象(例如一个`dict`)到参数 `json`。
* 如果你需要发送 *Form Data* 而不是 JSON使用 `data` 参数。
* 要发送 *headers*,传 `dict` 给 `headers` 参数。
* 对于 *cookies*,传 `dict` 给 `cookies` 参数。
关于如何传数据给后端的更多信息 (使用`httpx` 或 `TestClient`),请查阅 <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX 文档</a>.
/// info | 信息
注意 `TestClient` 接收可以被转化为JSON的数据而不是Pydantic模型。
如果你在测试中有一个Pydantic模型并且你想在测试时发送它的数据给应用你可以使用在[JSON Compatible Encoder](encoder.md){.internal-link target=_blank}介绍的`jsonable_encoder` 。
///
## 运行起来 { #run-it }
之后,你只需要安装 `pytest`。
确保你创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装,例如:
<div class="termy">
```console
$ pip install pytest
---> 100%
```
</div>
他会自动检测文件和测试,执行测试,然后向你报告结果。
执行测试:
<div class="termy">
```console
$ pytest
================ test session starts ================
platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: /home/user/code/superawesome-cli/app
plugins: forked-1.1.3, xdist-1.31.0, cov-2.8.1
collected 6 items
---> 100%
test_main.py <span style="color: green; white-space: pre;">...... [100%]</span>
<span style="color: green;">================= 1 passed in 0.03s =================</span>
```
</div>