pytest:为每个测试函数设置一个模拟
pytest: setup a mock for every test function
为 python 项目创建单元测试我们正在达到这种 'template'
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"部分在一些测试用例中是重复的,所以我想提取配置到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
11=] 文档和 unittest
文档中的 setup
。
但是,这些功能在实践中的使用很快就会失控,并且有可能创建不可读的测试代码。它有两种形式,一种是共享夹具设置变得太大(太笼统),使得 reader 很难理解与特定测试用例实际相关的内容。第二个是,测试代码不再是独立的,似乎魔法发生在外面。 Meszaros 将生成的测试气味称为 'Obscure Test',上述场景称为 'General Fixture' 和 'Mystery Guest'。
我的建议是,更喜欢从每个测试中显式调用的辅助函数/方法。你可以有几个,给它们起描述性的名字,这样就可以保持你的测试代码的可读性,而不需要先 reader 来搜索文件来找到任何 'automagic' 东西。在您的示例中,测试可能如下所示:
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...
为 python 项目创建单元测试我们正在达到这种 'template'
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"部分在一些测试用例中是重复的,所以我想提取配置到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
11=] 文档和 unittest
文档中的 setup
。
但是,这些功能在实践中的使用很快就会失控,并且有可能创建不可读的测试代码。它有两种形式,一种是共享夹具设置变得太大(太笼统),使得 reader 很难理解与特定测试用例实际相关的内容。第二个是,测试代码不再是独立的,似乎魔法发生在外面。 Meszaros 将生成的测试气味称为 'Obscure Test',上述场景称为 'General Fixture' 和 'Mystery Guest'。
我的建议是,更喜欢从每个测试中显式调用的辅助函数/方法。你可以有几个,给它们起描述性的名字,这样就可以保持你的测试代码的可读性,而不需要先 reader 来搜索文件来找到任何 'automagic' 东西。在您的示例中,测试可能如下所示:
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...