Usage¶
The copie
fixture will allow you to copy
a template and run tests against it. It will also clean up the generated project after the tests have been run.
For these examples, let’s assume the current folder is a copier template. it should include a copier.yml
file and a template
folder containing jinja templates.
Note
The name of the templlate folder can be anything as long as it matches the _subdirectory
key in the copier.yml
file.
demo_template/
├── template
│ └── README.rst.jinja
├── tests/
│ └── test_template.py
└── copier.yaml
the copier.yaml
file has the following content:
repo_name:
type: str
default: foobar
short_description:
type: str
default: Test Project
_subdirectory: template
And the readme template is:
{{ repo_name }}
===============
{{ short_description }}
default project¶
Use the following code in your test file to generate the project with all the default values:
def test_template(copie):
result = copie.copy()
assert result.exit_code == 0
assert result.exception is None
assert result.project_dir.is_dir()
with open(result.project_dir / "README.rst") as f:
assert f.readline() == "foobar\n"
It will generate a new repository based on your template, eg:
foobar/
└── README.rst
the Return
object can then be used to access the process outputs:
result.project_dir
result.exception
result.exit_code
result.answers
The temp folder will be cleaned up after the test is run.
Custom answers¶
Use the extra_answers
parameter to pass custom answers to the copier.yaml
questions.
The parameter is a dictionary with the question name as key and the answer as value.
def test_template_with_extra_answers(copie):
result = copie.copy(extra_answers={"repo_name": "helloworld"})
assert result.exit_code == 0
assert result.exception is None
assert result.project_dir.is_dir()
with open(result.project_dir / "README.rst") as f:
assert f.readline() == "helloworld\n"
Custom template¶
By default copy()
looks for a copier template in the current directory.
This can be overridden on the command line by passing a --template
parameter to pytest:
pytest --template TEMPLATE
You can also customize the template directory from a test by passing in the optional template
parameter:
@pytest.fixture
def custom_template(tmp_path) -> Path:
# Create custom copier template directory
(template := tmp_path / "copier-template").mkdir()
questions = {"custom_name": {"type": "str", "default": "my_default_name"}}
# Create custom subdirectory
(repo_dir := template / "custom_template").mkdir()
questions.update({"_subdirectory": "custom_template"})
# Write the data to copier.yaml file
(template /"copier.yaml").write_text(yaml.dump(questions, sort_keys=False))
# Create custom template text files
(repo_dir / "README.rst.jinja").write_text("{{custom_name}}\n")
return template
def test_copie_custom_project(copie, custom_template):
result = copie.copy(
template_dir=custom_template, extra_answers={"custom_name": "tutu"}
)
assert result.project_dir.is_dir()
with open(result.project_dir / "README.rst") as f:
assert f.readline() == "tutu\n"
Important
The template
parameter will override any --template
parameter passed on the command line.
Keep output¶
By default copie
fixture removes copied projects at the end of the test.
However, you can pass the keep-copied-projects
flag if you’d like to keep them in the temp directory.
Note
It won’t clutter as pytest only keeps the three newest temporary directories
pytest --keep-copied-projects