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

基于TDD方法编写Python API限流器的单元测试方案

TDD 模式下 API 限流器的测试用例设计

你梳理的TDD流程是正确的,针对当前的限流器场景,你可以先拆解核心功能点,每个功能点先写可运行的失败测试,再调整业务代码满足测试要求。

需覆盖的核心测试场景

按优先级排序如下:

  • 基础限流逻辑:单用户在时间窗口内请求数未达阈值时全部返回True,刚好达阈值的请求也返回True,超出阈值的请求返回False
  • 滑动窗口生效逻辑:用户请求触发限流后,等待完整的时间窗口过去,新的请求应该恢复返回True
  • 多用户隔离逻辑:不同clientID的计数完全独立,单个用户触发限流不会影响其他用户的请求结果
  • 边界场景验证:
    • 阈值设为1的极端场景,连续第二次请求直接返回False
    • 同一毫秒内的多个请求计数准确,不会因时间精度问题漏统计
    • 异常入参兼容(可选,比如阈值为0、时间窗口为负的场景,可按需增加校验逻辑)

测试代码示例

Python生态下推荐用pytest做测试框架,搭配freezegun模拟时间,避免测试过程中真的等待耗时。你需要先安装依赖:
pip install pytest freezegun

测试代码参考如下:

import pytest
from freezegun import freeze_time
# 替换成你自己的模块名,导入你写的PreciseRateLimiter
from rate_limiter import PreciseRateLimiter

# 测试1:窗口内请求未超阈值全部放行
def test_within_limit_all_allowed():
    limiter = PreciseRateLimiter(max_requests=3, time_interval_ms=1000)
    assert limiter.is_allowed("user_a") is True
    assert limiter.is_allowed("user_a") is True
    assert limiter.is_allowed("user_a") is True

# 测试2:超出阈值的请求被拦截
def test_over_limit_rejected():
    limiter = PreciseRateLimiter(max_requests=3, time_interval_ms=1000)
    # 先跑满3次额度
    for _ in range(3):
        limiter.is_allowed("user_a")
    # 第4次请求应该被拒绝
    assert limiter.is_allowed("user_a") is False

# 测试3:时间窗口滚动后请求恢复放行
def test_window_reset_allow_new_request():
    limiter = PreciseRateLimiter(max_requests=3, time_interval_ms=1000)
    with freeze_time() as frozen:
        # 跑满额度触发限流
        for _ in range(3):
            limiter.is_allowed("user_a")
        assert limiter.is_allowed("user_a") is False
        # 快进1秒,度过完整的时间窗口
        frozen.tick(1)
        # 新请求应该可以正常放行
        assert limiter.is_allowed("user_a") is True

# 测试4:多用户计数互不干扰
def test_multi_user_isolated():
    limiter = PreciseRateLimiter(max_requests=2, time_interval_ms=1000)
    # 用户A跑满额度
    limiter.is_allowed("user_a")
    limiter.is_allowed("user_a")
    assert limiter.is_allowed("user_a") is False
    # 用户B不受影响
    assert limiter.is_allowed("user_b") is True
    assert limiter.is_allowed("user_b") is True
    assert limiter.is_allowed("user_b") is False

注意事项

你当前的实现存在逻辑问题:计算时间差时取的是请求列表的最后一个元素(最新请求),而滑动窗口限流应该判断最早的那个请求是否超出时间窗口,你运行测试后就能复现这个问题,调整业务代码直到所有测试通过后,再做代码重构即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:24:04