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

如何使用parametrize测试返回值为None或非None?

问题:如何用pytest参数化测试返回值为None或非None的场景?

我有一个方法,在某些异常场景下应返回None,其他情况则返回复杂结果。示例方法foo如下:

import typing

def foo(x: int) -> typing.Optional[float]:
    if x == 0 or x == 10:
        return None
    else:
        return 1/x

我已针对正常场景编写单元测试验证复杂结果,现在想编写测试,验证异常场景返回None、正常场景返回非None。尝试使用pytest的parametrize参数化测试:

import pytest

@pytest.mark.parametrize("x, target",
                     [(0, None), (10, None), (5, not None)])
def test_foo(x, target):
    assert foo(x) is target

期望第三个测试用例执行assert foo(5) is not None,但not None会被解析为True,导致断言foo(x) is True失败。请问如何使用parametrize正确测试返回值为None或非None?


可行解决方案

方案1:传入断言判断函数

把target换成判断逻辑的函数,在测试中调用函数验证结果:

import pytest
import typing

def foo(x: int) -> typing.Optional[float]:
    if x == 0 or x == 10:
        return None
    else:
        return 1/x

@pytest.mark.parametrize("x, validator", [
    (0, lambda res: res is None),
    (10, lambda res: res is None),
    (5, lambda res: res is not None)
])
def test_foo(x, validator):
    result = foo(x)
    assert validator(result)

方案2:用布尔标记分支处理断言

给参数化用例传入一个布尔标记,在测试中根据标记执行对应断言:

import pytest
import typing

def foo(x: int) -> typing.Optional[float]:
    if x == 0 or x == 10:
        return None
    else:
        return 1/x

@pytest.mark.parametrize("x, should_be_none", [
    (0, True),
    (10, True),
    (5, False)
])
def test_foo(x, should_be_none):
    result = foo(x)
    if should_be_none:
        assert result is None
    else:
        assert result is not None

方案3:拆分场景为独立参数化测试

如果场景区分明确,拆成两个独立的参数化测试,逻辑更直观:

import pytest
import typing

def foo(x: int) -> typing.Optional[float]:
    if x == 0 or x == 10:
        return None
    else:
        return 1/x

@pytest.mark.parametrize("x", [0, 10])
def test_foo_returns_none(x):
    assert foo(x) is None

@pytest.mark.parametrize("x", [5, 3, 7])
def test_foo_returns_non_none(x):
    assert foo(x) is not None

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:10:25