Dynamic fixture creation for your tests
A Python port of node-fixturify-project
pip install -U python-fixturify-projector install with Poetry
poetry add python-fixturify-project --devpython-fixturify-project is a Python package that provides a way to create dynamic fixtures for your tests. Fixtures are real directories and files, written to a temporary directory.
from python_fixturify_project import Project
dir_json = {
"valid_file.txt": "some text",
"nested_dir": {
"valid_empty_file.txt": "",
"another_nested_empty_dir": {},
"another_nested_dir": {
"last_nested_empty_dir": {},
"final_text_file.txt": "some text",
},
},
}
# create a new project with the given directory structure
project = Project(files=dir_json)
# add new files to the project, merging with the existing directory structure
p.write({
"new_file.txt": "some text"
})
# read the actual contents on disc
actual_dir_json = p.read()By default, the read() function will ignore all hidden files and directories in your Project file structure. This can be overridden by using the ignore_patterns constructor argument, which
takes a list of glob pattern strings. Any patterns provided to the ignore_patterns argument will be used in an exclusive manner. For example:
files = {
".git": {
"a_nested_dir": {}
},
".github": {
"ignore_me": {},
"do_not_ignore_me": {
"a_file": "some text"
}
},
"ignore_me": "some text",
"do_not_ignore_me": "some text",
}
# Default ignore_patterns is ["**/.git", "**/.git/**"]
project = Project(ignore_patterns=["**/.git", "**/.git/**", "**/ignore_me"])
project.write(files)
assert project.read() == {
'.github': {
'do_not_ignore_me': {
'a_file': 'some text',
},
},
'do_not_ignore_me': 'some text',
}python-fixutrify-project becomes even more useful when combining it with tools like pytest and something like syrupy, which uses jest-like snapshots for testing. The example below combines python-fixturify-project with pytest's fixtures, and syrupy to create a snapshot test.
First, we define a fixture to setup and teardown our Project instance:
# conftest.py
import pytest
from python_fixturify_project import Project
@pytest.fixture
def project():
project = Project()
yield project
project.dispose()This fixture uses pytest's yield fixture pattern, which allows us to run some code after the test has completed. In this case, we use the dispose() method to remove the temporary directory created by python-fixturify-project.
from python_fixturify_project import Project
def test_mutating_project(project, snapshot):
project.write({
"a_file.txt": "some text",
"a_dir": {
"another_file.txt": "some text",
},
"path": {
"to": {
"a_file.py": "# some python code",
},
},
})
mutate_files_for_some_reason(p.base_dir)
# ensure mutations were as expected
assert project.files == snapshotOr you can use the project.get method to get the path to a file in the project.
from python_fixturify_project import Project
def test_mutating_project(snapshot):
project.write({
"a_file.txt": "some text",
"a_dir": {
"another_file.txt": "some text",
},
"path": {
"to": {
"a_file.py": "# some python code",
},
},
})
mutate_files_for_some_reason(p.base_dir)
# ensure mutations were as for single file
assert project.get('path/to/a_file.py') == snapshot(name='path/to/a_file.py')If you want to skip the dispose() call, you can set the FIXTURIFY_SKIP_DISPOSE environment variable to 1.
FIXTURIFY_SKIP_DISPOSE=1 pytestThis can be useful if you want to inspect the contents of the temporary directory after the test has completed.
This project is licensed under the terms of the MIT license. See LICENSE for more details.