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

如何使用pytest monkeypatch模拟多个argv参数?

问题解决方法

你的代码有两个核心问题导致测试失败:

  1. argparse参数类型错误:你在foo()里定义的是位置参数(不带--前缀),但测试里却用了--animal这种可选参数的写法,argparse会把--animal当成位置参数的值,自然找不到真正需要的animal和name参数。
  2. sys.argv被重复覆盖:你连续两次调用m.setattr(sys, 'argv', ...),第二次的赋值直接覆盖了第一次,最终sys.argv里只有--name相关内容,完全缺失animal参数,引发参数缺失报错。

修改后的位置参数版本代码

### foo.py ###
import argparse
import pytest
import sys

@pytest.mark.parametrize('animal_input, name_input', [('cat', 'tom')])
def test_get_bake_progress(monkeypatch, animal_input, name_input):
    with monkeypatch.context() as m:
        # sys.argv[0]为脚本名(可随便填,argparse仅需占位),后续跟位置参数值
        m.setattr(sys, 'argv', ['foo.py', animal_input, name_input])
        assert foo() == animal_input

def foo():
    parser = argparse.ArgumentParser()
    parser.add_argument('animal')
    parser.add_argument('name')
    args = parser.parse_args()
    animal = args.animal
    name = args.name
    return animal

若想改为可选参数(带--前缀)的版本

如果你原本计划把animal和name做成带--的可选参数,可按以下方式修改:

### 可选参数版本 foo.py ###
import argparse
import pytest
import sys

@pytest.mark.parametrize('animal_input, name_input', [('cat', 'tom')])
def test_get_bake_progress(monkeypatch, animal_input, name_input):
    with monkeypatch.context() as m:
        m.setattr(sys, 'argv', ['foo.py', '--animal', animal_input, '--name', name_input])
        assert foo() == animal_input

def foo():
    parser = argparse.ArgumentParser()
    parser.add_argument('--animal', dest='animal')
    parser.add_argument('--name', dest='name')
    args = parser.parse_args()
    animal = args.animal
    name = args.name
    return animal

补充说明:

  • 用@pytest.mark.parametrize把测试参数组合成元组,更清晰地传递一组测试数据。
  • sys.argv的第一个元素必须保留脚本名占位,argparse解析时会自动忽略该值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:24:20