【问题标题】:Unit test python udev interaction单元测试 python udev 交互
【发布时间】:2012-10-16 02:33:22
【问题描述】:

我继承了一些 python 代码,它编写了一个新的 '/etc/udev/rules.d' 映射文件,然后对 udev 进行子进程调用以使其刷新其设备列表:

call(['/sbin/udevadm', 'trigger', '--action=change'])

触发器调用是必要的,因为我们需要更新映射,而不想拔下并重新插入正在映射的设备。我的问题是“调用”行在某一点被删除,导致程序其他部分的副作用不明显,因此没有被捕获。

我通常的解决此类问题的方法是对该方法(写入映射文件并调用触发器)进行单元测试以强制执行预期的行为,但这种行为似乎超出了单元测试的范围。这是一个系统调用,更不用说 udevadm 触发器需要 sudo 访问权限。我不知道在这种情况下如何/模拟什么。

我考虑过使用 pyudev 库,因为我看到它可以模拟 udev 的某些行为,但它看起来不能模拟触发行为(或者甚至访问它)。

没有抛出一个大的“#永远不要删除这条线!”在“呼叫”行上方,我可以在这里做些什么来防止将来将其删除吗? “不要删除”行很容易被忽略,比如一年后没有人知道它为什么会出现。

【问题讨论】:

    标签: python udev


    【解决方案1】:

    这是我在这种情况下决定做的事情,如果有人不同意我的回答,请加入!

    这是一个二人组。

    首先,我包装了我关心的呼叫,并在我的代码中将直接“呼叫”切换到此。

    class UdevWrapper:
        def udevadm_trigger(self):
            call(['/sbin/udevadm', 'trigger', '--action=change'])
    

    (该类包含的内容不止这些,为了清楚起见,这里只是简化了)

    接下来我模拟了包装器方法并进行了测试以确保它被调用

    @patch.object(utils.UdevWrapper,'udevadm_trigger')
    def test_trigger_called(self,mock_udevadm_trigger):
        mock_udevadm_trigger.return_value = True
    
        # name changed for clarity
        ClassWhereTriggerCalled.func()
        assert mock_udevadm_trigger.called
    

    这样做的灵感来自于阅读Behaviour Driven Development。 BDD 的整个想法对我来说是全新的,所以我不确定 BDD 支持者在风格/功能上会如何看待我的解决方案,但它确实符合我的要求 - 如果在未来。

    我计划在未来将其切换为使用 monkeypatch,这样我就可以创建一个可以检查状态的存根函数(调用触发器的顺序也很重要)。不过原理还是一样的:

    1. 包装在可以模拟的方法中
    2. 编写测试以确保正确的功能行为
    3. 模拟包装方法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 2023-03-17
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多