python - pytest:为每个测试函数设置一个模拟
问题描述
为 python 项目创建单元测试,我们正在达到这种“模板”
from unittest import TestCase
from unittest.mock import patch, Mock
@patch('......dependency1')
@patch('......dependency2')
@patch('......dependencyn')
class MyTest(TestCase):
def test_1(self, mock1, mock2, mockn):
# setup mock1 & mock2...
# call the subject case 1
# assert response and/or interactions with mock1 and mock2...
def test_2(self, mock1, mock2, mockn):
# setup mock1 & mock2...
# call the subject case 2
# assert response and/or interactions with mock1 and mock2...
关键是,有时“设置”部分在某些测试用例中重复,所以我想将配置提取到setUp()
方法中,例如,以下是伪代码:
def setUp(self):
mock1.foo.return_value = 'xxx'
mock2.goo.side_effect = [ ... ]
def test_1(self, mock1, mock2, mockn):
# default setup is perfect for this test
def test_2(self, mock1, mock2, mockn):
# this time I need...
mock2.goo.side_effect = [ ... ]
有没有可能实现这个想法?
解决方案
两者都pytest
提供unittest
了您所询问的可能性,并且对于这两个功能都在各自的文档中通过示例进行了解释:fixture
在pytest
文档和文档setup
中查找unittest
。
然而,在实践中使用这些特性很快就会失控,并且容易产生不可读的测试代码。它有两种形式,一种是共享夹具设置变得太大(太笼统),使读者难以理解与特定测试用例实际相关的内容。第二个是,测试代码不再是自包含的,似乎魔法发生在外面。Meszaros 将产生的测试气味称为“Obscure Test”,上述场景称为“General Fixture”和“Mystery Guest”。
我的建议是,更喜欢从每个测试中显式调用的辅助函数/方法。您可以拥有其中的几个,给它们起描述性的名称,这样您的测试代码就可以保持可读性,而无需阅读器首先搜索文件以找到任何“自动”的东西。在您的示例中,测试可能如下所示:
def test_1(self, mock1, mock2, mockn):
default_setup(mock1, mock2, mockn)
# further test code...
def test_2(self, mock1, mock2, mockn):
default_setup(mock1, mock2, mockn)
setup_mock2_to_behave_as_xxx(mock2)
# further test code...
def test_3(self, mock1, mock2, mockn):
setup_mock1_to_always_xxx(mock1)
setup_mock2_to_behave_as_xxx(mock2)
setup_mockn_to_xxx(mockn)
# further test code...
推荐阅读
- sql - 使用 SQL、VB.NET 和 Access 进行区分大小写的登录
- python - 在多处理中清理子进程
- python - 当整列与填充值匹配时,Pandas 数据框子设置返回 NaN
- python - 我可以让 SVM 在大型数据集上运行得更快吗?
- javascript - 如何将 data-* attr 发送到 js 函数?
- database - 来自 3 个 CSV 文件的关系表
- css - 更改导航栏菜单的字体类型和背景颜色
- git - 有没有办法恢复已删除的 GitHub 存储库,其中包含本地保存的代码和提交历史记录?
- javascript - 如何禁用 kendo mvc 多选中的初始值,以便它们不会被取消选择?
- applescript - Aperture 导出导入脚本