测试有时需要调用依赖于全局设置的功能,或者调用不易测试的代码(如:网络访问)

monkeypatch fixture可以安全的设置/删除属性、字典项或环境变量,或修改sys.path以进行导入

monkeypath fixture提供了以下帮助方法,用于安全的修补和模拟测试中的功能

  • monkeypatch.setattr(obj,name,value,raising=True)
  • monkeypatch.delattr(obj,name,raising=True)
  • monkeypatch.setitem(mapping,name,value)
  • monkeypatch.delitem(obj,name,rasing=True)
  • monkeypatch.setenv(name,value,prepend=None)
  • monkeypatch.delennv(name,raising=True)
  • monkeypatch.syspath_prepend(path)
  • monkeypatch.chdir(path)
  • monkeypatch.context()

所有修改将在请求的测试函数或fixture完成后撤销,raising参数决定如果设置/删除操作的目标不存在,是否会引发KeyError或AttributeError

一.使用场景

1.为测试修改函数行为或类属性

如:有一个API调用或数据库连接,在测试中不会执行,但知道预期的输出结果,使用monkeypatch.setattr执行期望的测试行为修补函数或属性,包括自己的函数,使用monkeypatch.delattr在测试中删除函数或属性

2.修改字典的值

如:有一个全局配置,想为某些测试用例进行修改,使用monkeypatch.setitem修补测试中的字典,monkeypatch.delitem可用于删除项

3.修改测试的环境变量

如:测试在环境变量缺失时程序行为,或将多个值设置为已知变量,monkeypatch.setenv和monkeypatch.delenv可用于这些修补

4.修改路径

使用monkeypatch.setenv("PATH",value,prepend=os.pathsep)修改$PATH,并使用monkeypatch.chdir在测试期间更改当前工作目录的上下文

5.修改系统路径

使用monkeypatch.syspath_prepend修改sys.path,这也会调用pkg_resources.fixup_namespace_packages和importlib.invalidate_caches()

6.修补

使用monkeypatch.context仅在特定作用域内应用修补,这有助于控制复杂fixture的清理或对标准库(stdlib)的修补

二.Monkeypatching函数

用于处理用户目录的场景

在测试环境中,不希望测试依赖于正在运行的用户,monkeypatch可以用于修补依赖于用户的函数,使其始终返回特定值

在以下代码中,monkeypatch.setattr用于修补Path.home,以便在运行测试时始终使用已知的测试路径Path("/abc"),这消除了测试对正在运行用户的任何依赖,必须在调用将使用修补函数的函数之前调用monkeypatch.setattr,测试函数完成后,Path.home的修改将被撤销

三.Monkeypatching返回对象:构建mock类

monkeypatch.setattr可以与类结合使用,以模拟函数返回的对象而不是值

以下代码接受一个API URL并返回JSON响应

monkeypatch使用mock_get函数对requests.get应用模拟,mock_get函数返回MockResponse类的一个实例,该实例有一个json()方法,被定义为返回一个已知的测试字典,并且不需要任何外部API连接

以下的代码可以根据您正在测试的场景构建具有适当复杂度的MockResponse类,构建返回值包含True的ok属性,或者根据输入字符串从模拟的json()方法返回不同的值,此模拟可以通过使用fixture在测试之间共享

四.全局修补

阻止”request“库在所有测试中执行HTTP请求

这个autouse fixture将为每个测试函数执行,它将删除方法request.session.Session.request,以便测试中任何创建HTTP请求的尝试都将失败

注:

不建议修复open\compile等内置函数,因为它会破坏pytest的内部机制,如果无法避免,传递--tb=native\--assert=plain和--capture=no可能会有所帮助,尽管不能保证

修补stdlib函数和pytest使用的一些第三方库可能会破坏pytest本身,因此在这些情况下,建议使用MonkeyPatch.context()将修补限制在您想要测试的代码块中

五.Monkeypatching环境变量

如果正在使用环境变量,通常需要为了测试目的安全的更改其值或从系统中删除它们

monkeypatch提供了使用setenv和delenv方法来实现此目的机制

有两种潜在路径,首先,USER环境变量被设置为一个值,其次,USER环境变量不存在,使用monkeypatch可以安全的测试这两种路径,而不会影响正在运行的环境

可以移入fixture共享

六.Monkeypatching字典

momkeypatch.setitem可用于在测试期间安全地将字典地值设置为特定值

以下是简化地连接字符串实例代码

可以将DEFAULT_CONFIG修改为特定值

使用monkeypatch.delitem来删除值

fixture地模块化特性提供了灵活性,可以为每个潜在地模拟定义单独地fixture,并在需要地测试中引用它们

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐