【问题标题】:How to test a function that creates a directory?如何测试创建目录的函数?
【发布时间】:2015-09-23 19:44:04
【问题描述】:

如何在 Python 中测试创建目录的函数?可以举个例子make_directory_test()函数吗?

def make_directory(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)

【问题讨论】:

    标签: python unit-testing testing


    【解决方案1】:

    只需测试该目录是否存在

    def test_make_directory(self):
        directory_path = '...' # somepath
    
        make_directory(directory_path)
    
        self.assertTrue(os.path.exists(directory_path))
    

    并确保在tearDownsetUp中的每个测试后删除单元测试中创建的所有目录,以确保测试的独立性

    【讨论】:

    • 在断言为真时缺少一个 )。
    • 我认为 self.assertFalse(os.path.exists(directory_path))make_directory 之前会有所改善。
    • 我认为这是不必要的,因为我提到所有单元测试都应该是独立的。因此,任何使用文件系统的测试都应该在 tearDown 中编写类似的内容。
    【解决方案2】:

    这里的一个好的做法是学习如何使用测试框架,如 mockflexmock

    此外,您应该使用 Python 的 unittest 框架。

    您的目标不一定是确保创建某些东西,而是确保调用它。所以你想要做的是模拟外部调用来帮助测试你的方法的正确流程。所以在这种情况下你应该模拟存在和makedirs。然后确保它被调用。那将是一个可接受的单元测试。你会做这样的事情:

    让我们假设您的主要代码位于一个名为 my_module.py 的模块中。因此,您可能想创建一个测试文件,我们将其命名为 test.py 以使其简单,并在您的单元测试中执行以下操作:

    from mock import patch
    import my_module
    import unittest
    
    
    class MyTest(unittest.TestCase):
        @patch('my_module.exists')
        @patch('my_module.makedirs')
        def test_create_dir(self, mock_make_dirs, mock_exists):
            mock_exists.return_value = True
    
            make_directory('thing_to_create')
    
            mock_make_dirs.assert_called_with('thing_to_create')
    

    所以,这里发生的事情是你告诉模拟你想模拟出 makedirs 并且存在。您正在使用 mock_exists.return_value 指定的 True 返回存在。然后您进行实际调用,您的模拟将在该方法调用中生效。最后一行mock_make_dirs.assert_called_with 将确保您的创建目录的方法将被实际调用。

    如果您仍想测试是否确实创建了某些东西

    在这种情况下,您可以做的可能是冒险使用上下文管理器并创建一个临时文件夹进行测试,完成您的工作以测试您的方法以及您必须做的任何其他事情,一旦您完成完成你的工作后,上下文管理器会自行销毁。

    有关上下文管理器的信息,请查看contextlib

    【讨论】:

    • 补丁函数是否应该使用@patch('os.path.exists')等?
    • 嗨@VinceMiller。使用模拟补丁的经验法则是,你模拟的是你正在测试的地方,而不是定义模块的地方。文档实际上很好地解释了这一点here
    • 我还是有点困惑,希望你能澄清。我认为我们必须修补os.path.exists 而不是module,否则它将是AttributeError。类似于post
    • 嗨@GabrielChu。我写了一个非常简单的例子来帮助说明here。使用 pytest 运行测试。除一项测试外,所有测试都将失败。特别是 os.path.exists 示例,因为这是 Python 中的一个库,如果您模拟 os.path.exists,它仍然有效,但我们希望避免这种情况,因为这实际上会在所有模块。我们只对模拟当前被测系统感兴趣,这是我们要测试的具体方法。 [在下一条消息中继续]
    • @GabrielChu - 通过使用相对于我们测试位置的路径执行模拟,我们只是在该上下文中模拟它。现在,这带来了我链接的示例。失败的测试向您展示了当您实际尝试通过引用其“定义”路径而不是它在您当前正在测试的代码部分中的用法来模拟“您”编写的模块时会发生什么。我认为提供的示例应该有助于澄清正在发生的事情。随意摆弄它并进行实验。
    猜你喜欢
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    相关资源
    最近更新 更多