python - 使用 mark.parametrize 装饰器时如何使用补丁装饰器?
问题描述
我有一个测试功能,可以修补一些东西。一旦我达到超过 2 或 3 个补丁,该功能开始看起来很糟糕
def test_bla():
with patch(...):
with patch(...):
with patch(...):
# test
所以我尝试开始使用装饰器。这是我的示例测试,当我介绍补丁装饰器时它会中断
import pytest
from unittest.mock import patch
class Example:
def _run(self, x):
return x
def run(self, x):
return self._run(x) + 1
@pytest.mark.parametrize('x', [1])
def test_example(x):
assert Example().run(x) == 2
@pytest.mark.parametrize('x', [1])
@patch('Example._run', return_value=0)
def test_example_failure(x):
with pytest.raises(AssertionError):
assert Example().run(x) == 2
这是我得到的错误:
platform linux -- Python 3.6.13, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: ..., configfile: pytest.ini
plugins: metadata-1.11.0
collected 0 items / 1 error
==================================================================================================== ERRORS ====================================================================================================
________________________________________________________________________________________ ERROR collecting test_patch.py ________________________________________________________________________________________
In test_example_failure: function uses no argument 'x'
=========================================================================================== short test summary info ============================================================================================
ERROR test_patch.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=============================================================================================== 1 error in 0.12s ===============================================================================================
我尝试更改装饰器的顺序(正如我在一些 SO 答案中看到的那样),但这并没有帮助。
我刚刚意识到的另一件事是没有参数化的测试参数是有效的!(我调整了一些代码,因为事实证明我无法从我自己的模块中修补一个类)
import pytest
import random
from unittest.mock import patch
class Example:
def _run(self, x):
return random.randint(0, 6)
def run(self, x):
return self._run(x) + 1
@pytest.mark.parametrize('x', [1])
def test_example(x):
assert Example().run(x) < 7
# @pytest.mark.parametrize('x', [1])
@patch('random.randint', return_value=0)
def test_example_failure(x): # <<< How the heck does this work? 'x' is not defined!!
with pytest.raises(AssertionError):
assert Example().run(x) == 2
解决方案
@patch
MagicMoc
正在向测试对象发送参数。如果要发送另一个参数,@pytest.mark.parametrize
则需要将另一个参数添加到测试中
@pytest.mark.parametrize('x', [1])
@patch('Example._run', return_value=0)
def test_example_failure(mocked_class, x):
with pytest.raises(AssertionError):
assert Example().run(x) == 2
# randint = <MagicMock name='randint' id='2158546057008'>
# x = 1
推荐阅读
- json - 将动态数据传递到 Flutter 中的多个页面
- java - If My application Installed in device then after Any Application install from play store then show Notification using my application
- c - Printing multiple variables in single printf() statement
- symfony - Expected value of type for association field , got "double" instead
- oauth-2.0 - Cortana 技能 Oauth2 错误 AADSTS90014:请求正文必须包含以下参数:“范围”
- node.js - npm 运行生产错误我无法破译
- matlab - 如何在 Matlab 中创建动态约束
- java - 生成连通图 java
- python - 如何在 python 中加载 R 的 .rda 神经网络模型
- python - 直接通过 Python Shell 从文件中读取