代码之家  ›  专栏  ›  技术社区  ›  Manu Artero Rajeev Dutta

pytest:为每个测试函数设置一个mock

  •  0
  • Manu Artero Rajeev Dutta  · 技术社区  · 5 年前

    为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 = [ ... ]
    

    0 回复  |  直到 5 年前
        1
  •  2
  •   Dirk Herrmann    5 年前

    两者兼而有之 pytest unittest 提供您正在询问的可能性,对于这两种功能,在各自的文档中都用示例进行了说明:查找 fixture pytest公司 文件和 setup 单元测试 文档。

    然而,在实践中使用这些特性很快就会失控,并且有创建不可读的测试代码的趋势。它有两种形式,一种是共享fixture设置变得太大(太普遍),这使得读者很难理解与特定测试用例实际相关的内容。第二个原因是,测试代码不再是自包含的,似乎魔法在外面发生了。Meszaros称产生的测试气味为“模糊测试”,上面的场景称为“一般固定装置”和“神秘客人”。

    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...