如何使用pytest模拟Python中的超时场景?
测试while循环超时功能的pytest用例写法
核心思路
验证超时逻辑的关键是mock time.time() 函数,直接让它返回超过end_time的数值,跳过真实的等待过程,直接触发循环的超时退出条件。
具体实现步骤
- 借助
pytest-mock的mockerfixture,替换掉函数中使用的time.time - 模拟
time.time的返回值,让它在循环判断时直接满足超时条件(返回值 > end_time) - 断言函数返回的
flag为False,同时确认do_something未被调用(超时场景不会触发条件分支)
示例代码
假设待测试的函数完整代码如下:
import time def wait_for_condition(condition_check, timeout=5): flag = False end_time = time.time() + timeout while time.time() < end_time: if condition_check(): do_something() flag = True break return flag def do_something(): pass
对应的超时测试用例:
def test_timeout_scenario(mocker): # 模拟time.time的返回值:先返回初始时间,再返回超时后的时间 mock_time = mocker.patch('time.time') initial_time = 1000 # side_effect列表模拟两次调用:第一次用于计算end_time,第二次触发超时 mock_time.side_effect = [initial_time, initial_time + 6] # 模拟永远不满足的条件 mock_condition = mocker.Mock(return_value=False) # mock do_something函数,用于验证是否被调用 mock_do_something = mocker.patch('__main__.do_something') # 调用待测试函数 result = wait_for_condition(mock_condition, timeout=5) # 断言结果符合预期 assert result is False # 确认条件检查被执行过 mock_condition.assert_called_once() # 确认超时场景下do_something未被调用 mock_do_something.assert_not_called()
注意事项
- 确保mock的是函数实际依赖的
time.time:如果待测试函数在my_module.py中,需要patchmy_module.time.time而非全局的time.time - 若要模拟循环多次检查后才超时的场景,可扩展
side_effect列表,前几次返回小于end_time的值,最后一次返回大于end_time的值
内容的提问来源于stack exchange,提问作者vkp
相关产品推荐
相关产品推荐

