直接断言随机函数输出会失败,因为random.random()等每次结果不同;应通过random.seed(42)固定全局随机状态,或用patch模拟特定随机序列。

为什么直接断言随机函数的输出会失败
因为 random.random()、random.choice() 等函数每次运行结果都不同,用 assert result == 0.42 这类固定值断言必然在第二次测试就失败。不是代码写错了,是没控制住随机源。
用 random.seed() 固定全局随机状态
最简单有效的方式是在测试开始前调用 random.seed(42)(数字可任选,但必须固定)。这会让后续所有依赖 random 模块的函数产生完全一致的序列。
常见错误:只在函数内部设 seed —— 没用,seed 必须在测试逻辑执行前设置,且要确保没有其他代码提前调用了 random 函数干扰状态。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 在每个测试函数开头第一行加
random.seed(42) - 或统一在
setUp()方法里设置(unittest) - 避免使用
time.time()或系统熵作为 seed,否则失去可重复性 - 注意:
numpy.random和random是两套独立状态,需分别设 seed
测试返回列表/字典等复合结构的随机函数
即使输出是乱序列表,只要 seed 固定,random.shuffle() 或 random.sample() 的结果也确定。但别直接 assert 列表全等——容易因顺序敏感失败。
更稳妥的做法:
- 用
sorted(actual)和sorted(expected)比对内容(如果顺序不重要) - 对 shuffle 后的列表,先验证长度和元素是否一致:
set(actual) == set(expected),再检查是否发生了重排(如actual != expected) - 若函数返回带随机键的字典(如用
uuid4()),应抽离随机生成逻辑,单独 mock
用 unittest.mock.patch 替换随机行为(适合复杂场景)
当函数内部调用多处随机操作、或混用 random / numpy.random / secrets 时,统一设 seed 容易漏控。这时直接 patch 更清晰。
示例:mock random.random 返回固定序列
from unittest.mock import patch
...
with patch('random.random') as mock_random:
mock_random.side_effect = [0.1, 0.9, 0.5]
result = my_random_function()
assert result == "expected_based_on_0.1_0.9_0.5"
关键点:
- patch 目标必须是被测函数「导入时看到的路径」,比如函数里写
from random import random,就得 patch'mymodule.random' - 用
side_effect而非return_value,才能支持多次调用返回不同值 - mock 后无需设 seed,彻底脱离随机依赖


















