Python 现代开发学习笔记

(二十一)核对请求、页面与失败后的记录

1. 用固定输入复现一次完整操作

# 项目文件:demos/api_roundtrip.py
# 登录后取得新令牌,提交JSON、读取列表、标记已读,所有动作操作同一数据库。
from webbook.lab import lab_client, login

with lab_client() as (client, _app, _database):
    csrf = login(client)
    headers = {"X-CSRF-Token": csrf}
    response = client.post(
        "/api/books",
        json={"title": "Python Web", "finished": False, "tags": ["网络"]},
        headers=headers,
    )
    book = response.json()
    print("创建", response.status_code, response.headers["location"], book["finished"])
    print("未读", len(client.get("/api/books?finished=0").json()["items"]))
    response = client.post(f"/api/books/{book['id']}/finish", headers=headers)
    print("标记", response.status_code, response.json()["finished"])
    print("已读", len(client.get("/api/books?finished=1").json()["items"]))

输出依次是创建 201、未读数量 1、标记后 True、已读数量 1。新增得到的 Location 可以继续 GET 查询;表单与 API 都能读到数据库里的同一份状态。

2. 数据库失败后回到事务起点

配套测试临时让 create_book 在执行插入后抛出数据库异常,再核对三个位置:客户端得到 500;服务器日志保留具体失败信息;新连接查询书籍数仍为 0。

这与“插入之前校验失败”不同。它实际经过了 INSERT,再通过事务回滚撤销,所以能验证失败时不会留下半次写入。

测试先插入一条再注入数据库错误,异常退出事务触发回滚,新连接读到零条,日志与客户端分别得到相应信息

测试客户端按第六章 fixture 的方式取得应用与独立数据库:

# 项目文件:web_project/tests/conftest.py
# 每项请求检查独立建库,两个演示账号的摘要在这个测试库中生成。
import httpx
import pytest
from webbook.app import BookApp
from webbook.database import initialize


@pytest.fixture
def app(tmp_path):
    path = tmp_path / "library.sqlite3"
    initialize(path)
    return BookApp(path, origin="http://book.test", cors_origins={"http://front.test"})


@pytest.fixture
def client(app):
    with httpx.Client(
        transport=httpx.WSGITransport(app=app),
        base_url="http://book.test",
        follow_redirects=False,
    ) as client:
        yield client
# 在web_project中检查字段、事务、会话、权限、转义与跨源响应。
uv run python -m pytest

3. 浏览器负责的行为单独观察

HTTPX 便于重复发送固定请求。表单导航、fetch、HTML 节点是否生成和 CORS 读取限制,还要实际经过浏览器。

配套核验使用浏览器完成登录、表单新增、刷新、按钮标记、JSON 显示、缺令牌写入、两种跨源来源和另一个账号的修改尝试。调试时也可以沿 Network 的一条请求,逐项对照输入、状态、Location、Cookie、响应文本与数据库记录。

从页面动作定位对应网络请求,逐项比较请求字段状态与响应,再核对数据库记录,避免只根据屏幕提示判断完成

笔记正文与全部题解 · Ctrl / ⌘ K