使用pytest进行测试的自定义嘲讽



我有一个代码库(如下所示),其中有一个包含我开发的代码的src目录,以及tp中的一些支持第三方库。

.
├── src
│   ├── f.py
│   └── __init__.py
├── tp
│   ├── __init__.py
│   └── sim.py
│
└── tests
# contents of src/f.py
#!/usr/bin/python
from tp.sim import sim
def somefunc():
sim()
# contents of tp/sim.py
#!/usr/bin/python
def sim():
print("Hello, I'm in sim.sim()")

我打算为src目录中的代码编写测试。在示例文件中可见,src目录中的代码依赖于tp中的文件。对于tp中的大多数函数,我打算将它们monkeypatch用于测试。测试文件的示例如下所示。

1 #!/usr/bin/python
2
3
4 import src
5 from src.f import somefunc
6 from tp.sim import sim
7
8
9 def deco(func):
10     def wrapper(*args, **kwargs):
11         print("I'm inside wrapper")
12         func(*args, **kwargs)
13
14     return wrapper
15
16
17 sim = deco(sim)
18
19 # setattr(src.f, 'sim', sim)
20 somefunc()

在上面的代码中,当monkeypatchingtp.sim.sim时,不会影响src.f.somefunc的行为(第20行)。只有当我们明确地修补名称空间src.f.sim中的函数sim(第19行)时,我们才会看到修补的函数。

我在src目录中有多个文件,这些import文件来自tpsrc,而这些文件又来自tp文件中的import

我的主要问题是,我如何确保我的猴痘修补函数始终是测试过程中使用的函数(即,如果我在测试设置中用mysim()修补tp.sim.sim(),那么该范围内的所有测试都会看到mysim())

如果您的测试代码导入:

from tp.sim import sim

f模块将具有指向sim函数的全局sim名称。在tp.sim的全局中更改sim不会神奇地更新模块f中的全局名称sim,因此f.sim将始终指向实函数。

因此,如果您想在不更改导入的情况下对sim函数进行猴痘修补,您可以尝试修补f模块的全局sim名称,意思是:src.f.sim

f中的导入更改为:会更容易理解

from tp import sim

在这种情况下,src.f获得指向sim模块的sim全局名称,该模块中的函数可以通过当前的修补方法进行修改。没有重复的sim函数名,没有意外。

最新更新