這個系列的下載邏輯大量操作檔案系統:建立目錄、寫入片段、檢查檔案大小、合併檔案、刪除多餘檔案。如果測試都真的去操作磁碟,會遇到幾個實際的麻煩:測試變慢(磁碟 I/O 比記憶體操作慢很多)、測試之間可能互相污染(前一個測試留下的檔案影響下一個測試)、測試環境需要清理機制避免留下垃圾檔案。
pyfakefs 怎麼讓程式碼「以為」自己在操作真實檔案系統pyfakefs 的用法def test_save_ts_writes_decrypted_content(fs: FakeFilesystem):
fs.create_dir('video/some-item')
# 底下所有 os.path、open() 等操作,實際上都作用在記憶體裡的假檔案系統
worker = Worker(http=mock_http, logger=Logger(), directory='video/some-item')
await worker.save_ts(segment, index=0, total=1)
assert fs.exists('video/some-item/00000.ts')
with open('video/some-item/00000.ts', 'rb') as f:
assert f.read() == expected_content
pyfakefs 會攔截 Python 標準函式庫裡跟檔案系統相關的呼叫(os.path、open、glob 等),讓它們實際操作一份存在記憶體裡的假檔案系統,而不是真的碰觸磁碟。對被測試的程式碼來說,這些呼叫的行為(回傳值、例外)都跟操作真實檔案系統一致,它完全不知道自己其實在操作一份假的。
這種策略能成立的前提是:pyfakefs 對常見檔案系統操作的模擬夠精確、夠貼近真實作業系統的行為——這是它作為一個被廣泛使用的函式庫本身的責任,而不是每個使用它的專案要自己驗證的事。這也是選擇「用現成、被大量驗證過的替身函式庫」而不是「自己刻一個假的檔案系統」的原因:自己刻的替身,行為精確度需要自己負全責;用現成函式庫,這份責任由這個函式庫社群共同分攤。
pyfakefs 能驗證的是「程式碼在檔案系統層級的邏輯對不對」(有沒有建對目錄、寫對內容、正確判斷檔案是否存在),但驗證不了跟實體磁碟相關的行為(例如磁碟空間不足、實際的 I/O 效能)。這類問題如果需要驗證,還是得靠其他方式(例如整合測試、實際環境的壓力測試),不是 pyfakefs 這種替身策略該負責的範圍。
你測試過依賴檔案系統的程式碼嗎?是真的在測試環境建立/刪除檔案,還是用類似 pyfakefs 這種替身策略?如果是前者,你有沒有遇過測試之間互相污染的狀況?
pyfakefs 讓程式碼在記憶體裡的假檔案系統上運作,行為貼近真實作業系統明天講加密邏輯的測試:先產生一份用已知金鑰加密的假資料,反過來驗證解密邏輯對不對。