如何为conftest中定义、fixture返回的类添加类型提示
问题描述
我有一个用于测试特定条件的类,代码如下:
class MyTester: @staticmethod def does_string_apply(my_string: str) -> bool: return my_string == 'Hello World'
为了在多个测试文件中复用这个类,我把它定义在conftest.py里,并写了一个fixture来提供这个类:
@pytest.fixture(name="my_tester") def fixture_my_tester() -> type[MyTester]: return MyTester
但测试用例里没有导入MyTester类,不知道该怎么给fixture参数添加类型提示:
def test_something(my_tester: type['What goes here?']) -> None: assert my_tester.does_string_apply("Hello")
解决方案
1. 使用字符串字面量直接引用类名
这是最简单的方式,直接把类名放在字符串里,类型检查工具(如mypy)会识别这个字符串引用:
def test_something(my_tester: type['MyTester']) -> None: assert my_tester.does_string_apply("Hello")
2. 从conftest导入MyTester类
conftest.py不仅用于pytest共享配置,也可以直接从中导入类,这样就能直接用类名做类型提示:
# 测试文件开头 from conftest import MyTester def test_something(my_tester: type[MyTester]) -> None: assert my_tester.does_string_apply("Hello")
3. 条件导入(避免运行时依赖问题)
如果担心导入会带来运行时问题,可以借助typing.TYPE_CHECKING常量,只在类型检查阶段导入:
from typing import TYPE_CHECKING if TYPE_CHECKING: from conftest import MyTester def test_something(my_tester: type['MyTester']) -> None: assert my_tester.does_string_apply("Hello")
TYPE_CHECKING在运行时为False,这段导入代码不会被执行,既满足类型检查需求,又不影响运行时逻辑。
4. 用Protocol定义接口(更灵活的解耦方式)
如果不想直接依赖MyTester类,可以定义一个Protocol描述它的接口,再用这个Protocol做类型提示:
from typing import Protocol, Type class TesterProtocol(Protocol): @staticmethod def does_string_apply(my_string: str) -> bool: ... def test_something(my_tester: Type[TesterProtocol]) -> None: assert my_tester.does_string_apply("Hello")
只要fixture返回的类符合这个Protocol的接口,类型检查就会通过,实现了代码解耦。
内容的提问来源于stack exchange,提问作者Mike van Dyke
相关产品推荐
相关产品推荐

