Implements a fake file system that mocks the Python file system modules.
—
Integration with popular Python testing frameworks including unittest and pytest. pyfakefs provides seamless integration through fixtures, base classes, decorators, and context managers to automatically patch filesystem modules during test execution.
Automatic pytest integration through the fs fixture that provides a clean fake filesystem for each test.
def fs() -> FakeFilesystem:
"""
pytest fixture that provides a FakeFilesystem instance.
Automatically patches all filesystem modules (os, os.path, pathlib, shutil, io, open)
and provides a clean fake filesystem for each test function.
Returns:
FakeFilesystem instance for creating files and directories
"""
def fs_class() -> FakeFilesystem:
"""
Class-scoped pytest fixture that provides a FakeFilesystem instance.
Same as fs fixture but shared across all test methods in a test class.
Returns:
FakeFilesystem instance for creating files and directories
"""
def fs_module() -> FakeFilesystem:
"""
Module-scoped pytest fixture that provides a FakeFilesystem instance.
Same as fs fixture but shared across all tests in a module.
Returns:
FakeFilesystem instance for creating files and directories
"""
def fs_session() -> FakeFilesystem:
"""
Session-scoped pytest fixture that provides a FakeFilesystem instance.
Same as fs fixture but shared across entire test session.
Returns:
FakeFilesystem instance for creating files and directories
"""Usage example:
import pytest
def test_file_operations(fs):
"""Test using the fs fixture."""
# Create test files
fs.create_file('/test/data.txt', contents='test data')
fs.create_dir('/test/subdir')
# Test file operations
import os
assert os.path.exists('/test/data.txt')
assert os.path.isfile('/test/data.txt')
assert os.path.isdir('/test/subdir')
with open('/test/data.txt', 'r') as f:
content = f.read()
assert content == 'test data'
def test_pathlib_operations(fs):
"""Test pathlib integration."""
from pathlib import Path
# Create test file
fs.create_file('/test/pathlib.txt', contents='pathlib test')
# Use pathlib
path = Path('/test/pathlib.txt')
assert path.exists()
assert path.is_file()
assert path.read_text() == 'pathlib test'Base test class that automatically sets up pyfakefs for unittest-based tests.
class TestCase(unittest.TestCase):
"""
Base test class that provides automatic pyfakefs setup.
Inherits from unittest.TestCase and automatically patches filesystem modules.
Provides access to the fake filesystem via the 'fs' attribute.
"""
fs: FakeFilesystem
def setUpPyfakefs(
self,
modules_to_reload: List[str] = None,
modules_to_patch: Dict[str, str] = None,
additional_skip_names: List[str] = None,
use_known_patches: bool = True,
use_cache: bool = True,
**kwargs
) -> None:
"""
Set up pyfakefs for this test case.
Args:
modules_to_reload: List of modules to reload after patching
modules_to_patch: Dict of module names to patch
additional_skip_names: Additional modules to skip patching
use_known_patches: Whether to use known patches for common modules
use_cache: Whether to use filesystem caching
"""
def tearDownPyfakefs(self) -> None:
"""Tear down pyfakefs and restore real filesystem modules."""
@classmethod
def setUpClassPyfakefs(
cls,
modules_to_reload: List[str] = None,
modules_to_patch: Dict[str, str] = None,
additional_skip_names: List[str] = None,
use_known_patches: bool = True,
use_cache: bool = True,
**kwargs
) -> None:
"""
Set up pyfakefs for the entire test class (Python 3.8+).
Args:
modules_to_reload: List of modules to reload after patching
modules_to_patch: Dict of module names to patch
additional_skip_names: Additional modules to skip patching
use_known_patches: Whether to use known patches for common modules
use_cache: Whether to use filesystem caching
"""Usage example:
import unittest
import os
from pyfakefs.fake_filesystem_unittest import TestCase
class MyTest(TestCase):
def setUp(self):
self.setUpPyfakefs()
def test_file_creation(self):
# Create a test file
self.fs.create_file('/test/example.txt', contents='Hello World')
# Test standard file operations
self.assertTrue(os.path.exists('/test/example.txt'))
with open('/test/example.txt', 'r') as f:
content = f.read()
self.assertEqual(content, 'Hello World')
def test_directory_operations(self):
# Create directory structure
self.fs.create_dir('/test/subdir')
self.fs.create_file('/test/subdir/file.txt', contents='test')
# Test directory operations
self.assertTrue(os.path.isdir('/test/subdir'))
files = os.listdir('/test/subdir')
self.assertEqual(files, ['file.txt'])Mixin class for adding pyfakefs functionality to existing test classes.
class TestCaseMixin:
"""
Mixin for adding pyfakefs to existing test classes.
Use this when you can't inherit from pyfakefs.TestCase but want
to add fake filesystem functionality to your tests.
"""
fs: FakeFilesystem
def setUpPyfakefs(self, **kwargs) -> None:
"""Set up pyfakefs for this test."""
def tearDownPyfakefs(self) -> None:
"""Tear down pyfakefs and restore real filesystem."""Usage example:
import unittest
from pyfakefs.fake_filesystem_unittest import TestCaseMixin
class MyExistingTest(unittest.TestCase, TestCaseMixin):
def setUp(self):
# Existing setup code
super().setUp()
self.setUpPyfakefs()
# Additional setup with fake filesystem
self.fs.create_file('/config.ini', contents='[section]\nkey=value')
def tearDown(self):
self.tearDownPyfakefs()
super().tearDown()
def test_config_reading(self):
# Test code that reads /config.ini
import configparser
config = configparser.ConfigParser()
config.read('/config.ini')
self.assertEqual(config['section']['key'], 'value')Decorator to patch filesystem modules for individual test methods.
def patchfs(
additional_skip_names: List[str] = None,
modules_to_reload: List[str] = None,
modules_to_patch: Dict[str, str] = None,
use_known_patches: bool = True,
use_cache: bool = True
) -> Callable:
"""
Decorator to patch filesystem modules for a single test function.
The decorated function receives a 'fs' parameter with the FakeFilesystem instance.
Args:
additional_skip_names: Additional modules to skip patching
modules_to_reload: List of modules to reload after patching
modules_to_patch: Dict of module names to patch
use_known_patches: Whether to use known patches for common modules
use_cache: Whether to use filesystem caching
Returns:
Decorated function with filesystem patching
"""Usage example:
import unittest
import os
from pyfakefs.fake_filesystem_unittest import patchfs
class MyTest(unittest.TestCase):
@patchfs
def test_with_fake_fs(self, fs):
# Create test files
fs.create_file('/test.txt', contents='test content')
# Test file operations
self.assertTrue(os.path.exists('/test.txt'))
with open('/test.txt', 'r') as f:
content = f.read()
self.assertEqual(content, 'test content')
def test_without_fake_fs(self):
# This test uses the real filesystem
passContext manager for temporary filesystem patching within test methods.
class Patcher:
"""
Context manager for temporarily patching filesystem modules.
Provides manual control over when filesystem patching is active.
"""
fs: FakeFilesystem
def __init__(
self,
additional_skip_names: List[str] = None,
modules_to_reload: List[str] = None,
modules_to_patch: Dict[str, str] = None,
use_known_patches: bool = True,
use_cache: bool = True
) -> None:
"""
Initialize the patcher.
Args:
additional_skip_names: Additional modules to skip patching
modules_to_reload: List of modules to reload after patching
modules_to_patch: Dict of module names to patch
use_known_patches: Whether to use known patches for common modules
use_cache: Whether to use filesystem caching
"""
def __enter__(self) -> 'Patcher':
"""Enter the context and start filesystem patching."""
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
"""Exit the context and stop filesystem patching."""
class Pause:
"""
Context manager for temporarily pausing filesystem patching.
Allows temporary access to the real filesystem during test execution.
"""
def __init__(self, patcher: Union[Patcher, TestCase, FakeFilesystem]) -> None:
"""
Initialize the pause context manager.
Args:
patcher: Patcher instance, TestCase, or FakeFilesystem to pause
"""
def __enter__(self) -> 'Pause':
"""Enter the context and pause filesystem patching."""
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
"""Exit the context and resume filesystem patching."""Usage example:
import os
from pyfakefs.fake_filesystem_unittest import Patcher
def test_with_context_manager():
# Code here uses real filesystem
with Patcher() as patcher:
# Create fake files
patcher.fs.create_file('/fake.txt', contents='fake content')
# Test with fake filesystem
assert os.path.exists('/fake.txt')
with open('/fake.txt', 'r') as f:
content = f.read()
assert content == 'fake content'
# Code here uses real filesystem againConfigure pyfakefs behavior for pytest runs.
def pytest_addoption(parser) -> None:
"""Add pyfakefs-specific command line options to pytest."""
def pytest_configure(config) -> None:
"""Configure pyfakefs for the pytest session."""Command line options:
# Skip patching specific modules
pytest --fs-skip-modules=module1,module2
# Use dynamic patching (slower but more compatible)
pytest --fs-no-cache
# Debug filesystem patching
pytest --fs-debugfrom typing import List, Dict, Callable, Any, Optional, Union
# Configuration types
ModulesToPatch = Dict[str, str]
ModulesToReload = List[str]
SkipNames = List[str]
# Decorator type
PatchfsDecorator = Callable[[Callable], Callable]Helper functions for managing user context and module reloading in tests.
def set_uid(uid: int) -> None:
"""
Set the current user ID for filesystem operations.
Args:
uid: User ID to emulate
"""
def set_gid(gid: int) -> None:
"""
Set the current group ID for filesystem operations.
Args:
gid: Group ID to emulate
"""
def get_uid() -> int:
"""
Get the current user ID being emulated.
Returns:
Current user ID
"""
def get_gid() -> int:
"""
Get the current group ID being emulated.
Returns:
Current group ID
"""
def reset_ids() -> None:
"""Reset user and group IDs to defaults."""
def is_root() -> bool:
"""
Check if currently emulating root user.
Returns:
True if uid == 0, False otherwise
"""
def reload_cleanup_handler(name: str) -> None:
"""
Cleanup handler for module reloading.
Args:
name: Module name to clean up
"""Usage example:
from pyfakefs.helpers import set_uid, set_gid, reset_ids, is_root
def test_permission_checks(fs):
# Test as non-root user
set_uid(1000)
set_gid(1000)
# Create file with restricted permissions
fs.create_file('/secret.txt', contents='confidential', st_mode=0o600)
# Test access as different user
set_uid(1001)
try:
with open('/secret.txt', 'r') as f:
content = f.read() # Should raise PermissionError
except PermissionError:
print("Access denied as expected")
# Reset to defaults
reset_ids()Integration with Python's doctest module for testing documentation examples.
def load_doctests(
loader: unittest.TestLoader,
tests: unittest.TestSuite,
ignore: Any,
module: Any,
additional_skip_names: List[str] = None,
**kwargs
) -> unittest.TestSuite:
"""
Load doctests with pyfakefs support.
Use this function in your test module's load_tests function to automatically
patch filesystem modules when running doctests.
Args:
loader: Test loader instance
tests: Existing test suite
ignore: Ignored parameter (for compatibility)
module: Module containing doctests
additional_skip_names: Additional modules to skip patching
**kwargs: Additional pyfakefs configuration options
Returns:
Updated test suite with doctests
"""Usage example:
import doctest
import unittest
from pyfakefs import fake_filesystem_unittest
def load_tests(loader, tests, ignore):
"""Load doctests with pyfakefs support."""
return fake_filesystem_unittest.load_doctests(
loader, tests, ignore, __name__
)
# Example doctest in your module:
def create_config_file():
"""
Create a configuration file.
>>> create_config_file()
>>> import os
>>> os.path.exists('/config/settings.ini')
True
>>> with open('/config/settings.ini', 'r') as f:
... content = f.read()
>>> 'debug=true' in content
True
"""
import os
os.makedirs('/config', exist_ok=True)
with open('/config/settings.ini', 'w') as f:
f.write('[DEFAULT]\ndebug=true\n')Install with Tessl CLI
npx tessl i tessl/pypi-pyfakefs