pyfakefs 是一个假文件系统,它模拟的是python的文件系统,简单来说,它提供了和python的os模块,Path模块一样的功能,所有的文件操作,例如创建,修改,删除,重命名等操作都是在内存中进行的。
做出一个假的文件系统,有什么用处呢,我最开始看到这个模块的介绍时,心中是一样的疑问,直至看到它的示例,才明白它的奥妙之处。我们在编写python模块时,如果这个模块的功能是和文件操作有关的,比如遍历某个文件夹,移动一些文件到另一个文件夹,如果你想做单元测试,就必须准备这些文件,麻烦的是随着测试的进行,这些文件都发生了变化,再次进行测试的时候,不得不重新创建他们。
pyfakefs就可以解决上面所提到的麻烦,来看一下官方示例
import os
from pyfakefs.fake_filesystem_unittest import TestCase
class ExampleTestCase(TestCase):
def setUp(self):
self.setUpPyfakefs()
def test_create_file(self):
file_path = '/test/file.txt'
self.assertFalse(os.path.exists(file_path))
self.fs.create_file(file_path)
self.assertTrue(os.path.exists(file_path))
self.fs.create_file(file_path) 创建了目标文件,第二个断言仍然是正确的,os.path.exists会认为这个文件是真实存在的,但/test/file.txt 从来没有在硬盘上被创建过,它只存在于内存中。os.path.exists方法之所以判断它存在,是因为pyfakefs对os模块打了补丁,或者说,已经替换掉了python内置的os模块。
pyfakefs 可以和pytest,unittest结合使用,也可以直接使用fake_filesystem_unittest.Patcher 来构建假的文件系统。
from pyfakefs.fake_filesystem_unittest import Patcher
patcher = Patcher()
patcher.setUp()
os.mkdir('hhh')
os.mkdir('hhh/ttt')
print(os.path.exists('hhh'))
print(os.listdir('hhh'))
with open('hhh/1.txt', 'w')as f:
f.write('ok')
with open('hhh/1.txt', 'r')as f:
print(f.read())
上面的代码,即便创建的文件夹目录是linux的格式,你却可以在windows下运行,打开文件,写入数据,读取数据,你在做文件操作时,感受不到任何变化,但这些文件从未在硬盘上存在过。
pyfakefs 支持python3.6+, 由于其实现的原理是通过打补丁的方式替换python内置的文件操作相关模块,因此如果一个文件操作的底层使用了c库,pyfakefs则不能保证正常运行,比如lxml 模块。
使用pip安装pyfakefs
pip install pyfakefs
使用这个模块,你对文件系统的任何操作都是在内存层面上的操作,不会影响到硬盘,这样带来的好处就是避免对硬盘上的文件造成不可挽回的破坏,在测试场景下,可以反复构建用于测试的文件环境,不需要任何人工参与。