缓存失效验证必须通过自动化脚本模拟完整生命周期并断言关键行为:明确触发机制(ttl/主动删除/刷新),用fakeredis精确控制过期,覆盖命中率、回源、新值写入及空值防护,并集成至pytest与ci阻断发布。

缓存失效有效性不能只靠“配置完就认为生效”,必须通过自动化脚本主动触发、观察、断言。核心是模拟真实业务中缓存从有效→过期→重建的完整生命周期,并验证关键节点行为是否符合预期。
明确失效触发方式与验证维度
先确认你系统中缓存失效是靠哪种机制:TTL自动过期?主动删除(如更新DB后del key)?还是刷新接口(如 /cache/refresh)?不同机制对应不同的脚本设计重点:
- TTL类:重点验证时间推进后 key 是否不可读、是否触发回源加载
- 主动删除类:重点验证删除操作执行后,下一次读是否立即回源、且新值写入缓存
- 刷新类:重点验证刷新请求返回成功后,后续读是否返回新数据、且 TTL 重置
用 fakeredis 模拟可控的过期过程(推荐)
避免依赖真实 Redis 实例,用 fakeredis 可精确控制时钟和状态:
- 在测试中调用
redis.setex("user:1001", 5, "old_data")设置 5 秒过期 - 不等待真实时间流逝,直接修改 fakeredis 内部时间戳:
redis._server.time = lambda: (int(time.time()) + 6, 0) - 再执行
redis.get("user:1001"),应返回None - 紧接着发起一次业务读请求(如调用你的 service 方法),检查返回值是否为新数据、且缓存中该 key 已存在并带新 TTL
断言缓存失效后的关键行为
仅检查 key 是否消失不够,要覆盖业务逻辑闭环:
-
命中率下降:在请求前后分别调用监控接口(如
/metrics)或 mock 埋点,确认cache_hit计数未增加、cache_miss+1 - 回源发生:mock 数据库查询方法,验证其被调用一次;或检查后端日志中对应 SQL / HTTP 请求出现
-
新值写入:get 缓存 key,确认值已更新,且
ttl("user:1001") > 0 -
空值防护生效(如适用):当 DB 查无结果时,检查是否写入了空标记(如
"NULL")且带短 TTL
集成到 pytest 流程中形成稳定检查点
把失效验证作为独立测试用例,而非辅助步骤:
- 用
@pytest.mark.parametrize覆盖不同 TTL 值(1s / 30s / 300s) - 每个用例包含 setup(预设缓存)、action(推进时间或触发删除)、assert(验证回源+新缓存)三段
- 在 CI 流水线中固定运行,失败即阻断发布——缓存失效失效,等于一致性裸奔











