【问题标题】:Most efficient way of cleaning up files after a test?测试后清理文件的最有效方法?
【发布时间】:2018-08-28 11:30:02
【问题描述】:

我编写了一些测试用例来测试我编写的函数。该功能是简单地计算特定目录中的文件数。最终,我将拥有另一个函数,该函数将以某种方式运行,具体取决于每个目录中有多少文件。在这种情况下,我正在使用两个目录。这是我的函数:
dir_handler.py

from pathlib import Path

def count_files_in_dir(dirpath):
    assert(dirpath.is_dir())
    file_list = []
    for file in dirpath.iterdir():
        if file.is_file():
            file_list.append(file)
    return len(file_list)  

这是我的测试用例:
test_dir_handler.py

from imports import *
import os
from main.dir_handler import count_files_in_dir


class DirHandlerTests(unittest.TestCase):

def test_return_count_of_zero_when_no_file_exists_in_input_dir(self):
    self.assertEqual(0, count_files_in_dir(INPUT_FILE_PATH))

def test_return_count_of_zero_when_no_file_exists_in_output_dir(self):
    self.assertEqual(0, count_files_in_dir(OUTPUT_FILE_PATH))

def test_return_count_of_one_when_one_file_exists_in_input_dir(self):
    with open(str(INPUT_FILE_PATH)+ "/"+"input.csv", "w") as file:
        self.assertEqual(1, count_files_in_dir(INPUT_FILE_PATH))

def test_return_count_of_one_when_one_file_exists_in_output_dir(self):
    with open(str(OUTPUT_FILE_PATH)+ "/"+"output.csv", "w") as file:
        self.assertEqual(1, count_files_in_dir(OUTPUT_FILE_PATH))

def test_return_count_of_two_when_two_files_exists_in_output_dir(self):
    with open(str(OUTPUT_FILE_PATH)+ "/"+"output.csv", "w") as file:
        with open(str(OUTPUT_FILE_PATH)+ "/"+"output2.csv", "w") as file:
            self.assertEqual(2, count_files_in_dir(OUTPUT_FILE_PATH))

#clearing up testing files at the end of test
def tearDown(self):
    try:
        os.remove(str(INPUT_FILE_PATH)+ "/"+"input.csv")
    except FileNotFoundError as e:
        pass
    try:
        os.remove(str(OUTPUT_FILE_PATH)+ "/"+"output.csv")
    except FileNotFoundError as e:
        pass

    try:
        os.remove(str(OUTPUT_FILE_PATH)+ "/"+"output2.csv")
    except FileNotFoundError as e:
        pass

if __name__ == '__main__':
    unittest.main()

如您所见,我必须单独删除“input2.csv”和“output2.csv”,这不是很有效。 INPUT_FILE_PATH 和 OUTPUT_FILE_PATH 都在同一个目录“files”下。所有测试都通过了,但我想在测试结束时就清理 INPUT_FILE_PATH 和 OUTPUT_FILE_PATH 目录的最佳方法提出建议。谢谢

编辑:
使用@rockport 的建议,我实现了一个 setUp / tearDown 方法。代码按预期工作,但仍然很混乱。它会在测试结束时清除 output_file 文件夹和 input_file 文件夹。我还实现了 pathlib 而不是 os,因为我将在 mac 和 windows 上运行和编辑代码。这是我的代码的一些更改

def setUp(self):
        self.input_file = INPUT_FILE_PATH.joinpath("input.csv")
        self.output_file = OUTPUT_FILE_PATH.joinpath("output.csv")
        self.output_file2 = OUTPUT_FILE_PATH.joinpath("output2.csv")

def test_return_count_of_one_when_one_file_exists_in_output_dir(self):
    with self.output_file.open(mode='w') as file:
        self.assertEqual(1, count_files_in_dir(OUTPUT_FILE_PATH))

def test_return_count_of_two_when_two_files_exist_in_output_dir(self):
    with self.output_file.open(mode='w') as file:
            with self.output_file2.open(mode='w') as file:
                self.assertEqual(2, count_files_in_dir(OUTPUT_FILE_PATH))

def tearDown(self):
    for file in INPUT_FILE_PATH.iterdir():
        try:
            file.unlink()
        except FileNotFoundError as e:
            pass
    for file in OUTPUT_FILE_PATH.iterdir():
        try:
            file.unlink()
        except FileNotFoundError as e:
            pass

【问题讨论】:

  • 请修复代码中的缩进。你这里有重复的测试功能吗?看起来像这样。
  • @rocksportrocker 删除了重复测试,谢谢
  • 无需打开文件。您创建文件处理程序file,以后不使用。
  • 我也有点担心OUTPUT_PATHINPUT_PATH 的来源。我会在 setUp 中创建临时文件夹。

标签: python unit-testing testing


【解决方案1】:

您想要的是shutil.rmtree,它将删除整个目录,包括其中的所有子目录和文件。之后,您可以使用os.mkdiros.makedirs 重新创建目录。这是一个例子:

import os
import shutil

shutil.rmtree(INPUT_FILE_PATH)
os.mkdir(INPUT_FILE_PATH)

【讨论】:

    【解决方案2】:

    如果您不想删除整棵树,您可以简单地将路径附加到列表并遍历列表以删除其中的每个路径

    pathlist = []
    
    def test_return_count_of_one_when_one_file_exists_in_output_dir(self):
        path = str(OUTPUT_FILE_PATH) + "/output.csv"
        pathlist.append(path)
        with open(path, "w") as file:
            self.assertEqual(1, count_files_in_dir(OUTPUT_FILE_PATH))
    

    然后:

    for path in pathlist:
        try:
            os.remove(path)
        except FileNotFoundError:
            pass
    

    【讨论】:

      【解决方案3】:

      最佳做法是实现setUp 方法,您可以在其中在临时文件夹中创建文件。然后你在这个文件夹上运行你的实际测试。最后不需要移除。

      单元测试不应依赖于环境,例如测试文件夹之外的文件。这就是我们在测试中使用固定装置的原因。


      您要求的简化可能是

      def tearDown(self):
      
          for p, f in ((INPUT_FILE_PATH, "input.csv"),
                       (OUTPUT_FILE_PATH, "output.csv"),
                       (OUTPUT_FILE_PATH, "output2.csv")):
              try:
                  os.remove(str(p) + "/" + f)
              except FileNotFoundError:
                  pass
      

      对于您的编辑,为什么不只是:

      def test_return_count_of_one_when_one_file_exists_in_output_dir(self):
          self.assertEqual(1, count_files_in_dir(OUTPUT_FILE_PATH))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        • 2010-09-05
        • 1970-01-01
        相关资源
        最近更新 更多