在 AssertionError 的情况下,在 'assert' 之后执行代码

Execute code after an 'assert' in case of AssertionError

我正在测试一个函数,其主要目的是将文件分配到该函数的参数中接收到的文件夹中。为此,我在我的根文件夹中创建了一个空文件,并测试了一些不同的路径参数。更明确地说,这是一个例子:

alocate_file('folder1','folder2','folder3', 'file.txt')

此行将导致此分配:

root/Downloads/folder1/folder2/folder3/file.txt

我的函数的一些额外特征:下载文件夹是隐式的,它接收一个列表作为参数并假定列表中的最后一个字符串是文件。

我的问题

测试此函数后,我删除了空文件(仅为测试目的而创建)和我的函数创建的所有文件夹。这是使用 shutil.rmtree after 断言完成的,这就是问题所在。 当测试失败时, 它引发了一个 AssertionError 并且那些文件夹和文件没有被删除,因为断言之后的代码没有被执行。这也会破坏其他测试,因为我对所有这些测试使用相同的文件和文件夹名称。然后我必须手动删除所有这些文件才能再次正确测试。

我考虑过使用固定装置,但我认为这不是一个好的解决方案,因为正如我所说,它测试不同路径的创建,它没有通用案例。我必须为每个测试创建单独的装置,这似乎是最好的方法。

这是我的一项测试有这个问题:

def test_alocate_file_three_level_path(root_path):
    # creates files in root
    file_path1 = os.path.join(root_path, 'test1.pdf')
    Path(file_path1).touch()
    # creates path for test
    test_path = os.path.join(root_path, 'Downloads', 'path1', 'path2','path3','test1.pdf')
    # function alocate the file to folders
    func_aux.alocate_file('path1', 'path2', 'path3', 'test1.pdf')
    # check if the file is there
    assert os.path.isfile(test_path) == True
    # remove the created file and folders
    remove_path = os.path.join(root_path, 'Downloads', 'path1')
    shutil.rmtree(remove_path)

我想知道我可以保证删除我为测试目的创建的所有文件夹和文件的唯一方法是为每个测试使用特定的固定装置还是有办法我可以在断言 之后始终执行代码,即使使用 AssertionError

您可以使用一个简单的 try... finally 块来管理它,因为如果断言未被验证,assert 会引发 AssertionError:

x = 1

try:
    assert x == 0
finally:
    print("this code will always run")

正如@hoefling 所建议的,我实现了一个创建临时目录的装置。修改我在 post 中提供的代码,结果如下:

@pytest.fixture(scope="module")
def temp_dir(root_path):
    down_path = os.path.join(root_path, 'Downloads', 'temp_dir')
    os.makedirs(down_path)
    yield down_path
    shutil.rmtree(down_path)


def test_alocate_file_three_level_path(root_path, temp_dir):
    # creates files in root
    file_path1 = os.path.join(root_path, 'test1.pdf')
    Path(file_path1).touch()
    # creates path for test
    test_path = os.path.join(temp_dir, 'path1', 'path2','path3','test1.pdf')
    # function alocate the file to folders
    func_aux.alocate_file('temp_dir', 'path1', 'path2', 'path3', 'test1.pdf')
    # check if the file is there
    assert os.path.isfile(test_path) == True

保证在测试结束时,所有的辅助文件都被删除了。对于那些不明白发生了什么的人,fixture 一直执行到 yield。之后,测试接收到它的值并完成它的工作。 AssertionError的独立性,当测试结束时,返回fixture和运行yield后的代码。