假设我想创建一个“utils”包,其中包含几个处理文件和文件夹的函数。我想做一次正确的,以便我可以使用他们在我的所有个人项目,而不是感觉到重新发明车轮每一次。顺便说一句,我还想学到两项:
我的职责是:
def removeanything(src):
"""
remove files or folders
"""
try:
os.remove(src)
print('File is removed')
except IsADirectoryError:
shutil.rmtree(src)
print('Folder is removed')
except FileNotFoundError:
print('File/folder is not existing')
except PermissionError:
print('Not allowed to suppress this file')您对我的异常处理有什么意见吗?我忘记了一个或多个例外吗?
为了继续,我为pytest编写了这个测试函数:
from pathlib import Path
import utils
#import pytest
def test_removeanything(tmp_path):
d = tmp_path / '.tmp_dir'
d.mkdir()
f = d / '.tmp_file'
f.touch()
# Test permission
d.chmod(mode=0o555)
utils.removeanything(f)
assert Path.exists(f)
# Test file deletion
d.chmod(mode=0o777)
utils.removeanything(f)
assert not Path.exists(f)
# Test folder deletion
utils.removeanything(d)
assert not Path.exists(d)由于我在测试方面非常新手,我想知道我是否包括所有合理的东西来断言我的功能?有没有其他更好的方法来做呢?是否有一种方法来断言预期的错误确实是由我的函数引起的?
谢谢!
发布于 2020-01-08 12:37:11
在doc注释中,您可以更清楚地了解该函数的功能:
os.remove和shutil.rmtree可能会抛出)调用removeanything("myfile")的人可能会期望在函数调用之后myfile不再存在。但是,在出现权限错误的情况下,它仍然存在。我认为这是一种特殊情况,因此我建议您不要捕获PermissionError,而是将其传播给调用方。
目前,该函数通过打印语句进行通信。这意味着函数的调用者无法知道实际发生了什么。您可以添加一个返回值,该返回值指示是否删除了文件、目录或任何内容。然后,您可能会考虑删除print语句,或者通过函数参数启用/禁用它,因为用户可能希望悄悄地删除文件。
将单个测试test_removeanything划分为多个测试( test_removeanything_deletes_file、test_removeanything_deletes_directory、test_removeanything_handles_permission_error )可能很有用。这样,如果测试失败,测试名称将为您提供更多关于哪里出错的信息。
通常,删除目录的函数要求它们是非空的.因此,测试删除空目录和非空目录是有意义的.
如果更改removeanything以使PermissionError传播到用户,则可以使用pytest.raises测试异常是否正确引发。
我认为removeanything这个名字可以更具体一些。毕竟,该函数不会从我的CD驱动器中删除CD ;)
发布于 2020-01-09 09:33:53
我已经以这种方式更新了我的代码,使用了pytest.fixtures和pytest提供的临时文件/文件夹。
from pathlib import Path
import os
import utils
import pytest
@pytest.fixture
def fd(tmp_path):
d = tmp_path / '.tmp_dir'
d.mkdir()
f = d / '.tmp_file'
f.touch()
return f,d
# Test permission
def test_permissions(fd):
with pytest.raises(PermissionError):
f,d = fd
d.chmod(mode=0o555)
utils.removeanything(f)
# Test file deletion
def test_delete_file(fd):
f,d = fd
utils.removeanything(f)
assert not Path.exists(f)
# Test non empty folder deletion
def test_delete_folder_nonempty(fd):
f,d = fd
utils.removeanything(d)
assert not Path.exists(d)
# Test empty folder deletion
def test_delete_folder_empty(fd):
f,d = fd
f.unlink()
utils.removeanything(d)
assert not Path.exists(d)考虑到可能的空目录,我添加了其他测试。关于test_permissions,上下文管理器跟踪错误是否被很好地引发。
https://codereview.stackexchange.com/questions/235278
复制相似问题