home / tils / til

Menu
  • GraphQL API

til: cookiecutter_pytest-for-cookiecutter.md

This data as json

path topic title url body html shot created created_utc updated updated_utc shot_hash slug
cookiecutter_pytest-for-cookiecutter.md cookiecutter Testing cookiecutter templates with pytest https://github.com/simonw/til/blob/main/cookiecutter/pytest-for-cookiecutter.md I added some unit tests to my [datasette-plugin](https://github.com/simonw/datasette-plugin) cookiecutter template today, since the latest features involved adding a `hooks/post_gen_project.py` script. Here's [the full test script](https://github.com/simonw/datasette-plugin/blob/503e6fef8e1000ab70103a61571d47ce966064ba/tests/test_cookiecutter_template.py) I wrote. It lives in `tests/test_cookiecutter_template.py` in the root of the repository. To run the tests I have to use `pytest tests` because running just `pytest` gets confused when it tries to run the templated tests that form part of the cookiecutter template. The pattern I'm using looks like this: ```python from cookiecutter.main import cookiecutter import pathlib TEMPLATE_DIRECTORY = str(pathlib.Path(__file__).parent.parent) def test_static_and_templates(tmpdir): cookiecutter( template=TEMPLATE_DIRECTORY, output_dir=str(tmpdir), no_input=True, extra_context={ "plugin_name": "foo", "description": "blah", "include_templates_directory": "y", "include_static_directory": "y", }, ) assert paths(tmpdir) == { "datasette-foo", "datasette-foo/.github", "datasette-foo/.github/workflows", "datasette-foo/.github/workflows/publish.yml", "datasette-foo/.github/workflows/test.yml", "datasette-foo/.gitignore", "datasette-foo/datasette_foo", "datasette-foo/datasette_foo/__init__.py", "datasette-foo/datasette_foo/static", "datasette-foo/datasette_foo/templates", "datasette-foo/README.md", "datasette-foo/setup.py", "datasette-foo/tests", "datasette-foo/tests/test_foo.py", } setup_py = (tmpdir / "datasette-foo" / "setup.py").read_text("utf-8") assert ( 'package_data={\n "datasette_foo": ["static/*", "templates/*"]\n }' ) in setup_py def paths(directory): paths = list(pathlib.Path(directory).glob("**/*")) paths = [r.relative_to(directory) for r in paths] return {str(f) for f in paths if str(f) != "."} ``` <p>I added some unit tests to my <a href="https://github.com/simonw/datasette-plugin">datasette-plugin</a> cookiecutter template today, since the latest features involved adding a <code>hooks/post_gen_project.py</code> script.</p> <p>Here's <a href="https://github.com/simonw/datasette-plugin/blob/503e6fef8e1000ab70103a61571d47ce966064ba/tests/test_cookiecutter_template.py">the full test script</a> I wrote. It lives in <code>tests/test_cookiecutter_template.py</code> in the root of the repository.</p> <p>To run the tests I have to use <code>pytest tests</code> because running just <code>pytest</code> gets confused when it tries to run the templated tests that form part of the cookiecutter template.</p> <p>The pattern I'm using looks like this:</p> <div class="highlight highlight-source-python"><pre><span class="pl-k">from</span> <span class="pl-s1">cookiecutter</span>.<span class="pl-s1">main</span> <span class="pl-k">import</span> <span class="pl-s1">cookiecutter</span> <span class="pl-k">import</span> <span class="pl-s1">pathlib</span> <span class="pl-v">TEMPLATE_DIRECTORY</span> <span class="pl-c1">=</span> <span class="pl-en">str</span>(<span class="pl-s1">pathlib</span>.<span class="pl-v">Path</span>(<span class="pl-s1">__file__</span>).<span class="pl-s1">parent</span>.<span class="pl-s1">parent</span>) <span class="pl-k">def</span> <span class="pl-en">test_static_and_templates</span>(<span class="pl-s1">tmpdir</span>): <span class="pl-en">cookiecutter</span>( <span class="pl-s1">template</span><span class="pl-c1">=</span><span class="pl-v">TEMPLATE_DIRECTORY</span>, <span class="pl-s1">output_dir</span><span class="pl-c1">=</span><span class="pl-en">str</span>(<span class="pl-s1">tmpdir</span>), <span class="pl-s1">no_input</span><span class="pl-c1">=</span><span class="pl-c1">True</span>, <span class="pl-s1">extra_context</span><span class="pl-c1">=</span>{ <span class="pl-s">"plugin_name"</span>: <span class="pl-s">"foo"</span>, <span class="pl-s">"description"</span>: <span class="pl-s">"blah"</span>, <span class="pl-s">"include_templates_directory"</span>: <span class="pl-s">"y"</span>, <span class="pl-s">"include_static_directory"</span>: <span class="pl-s">"y"</span>, }, ) <span class="pl-k">assert</span> <span class="pl-en">paths</span>(<span class="pl-s1">tmpdir</span>) <span class="pl-c1">==</span> { <span class="pl-s">"datasette-foo"</span>, <span class="pl-s">"datasette-foo/.github"</span>, <span class="pl-s">"datasette-foo/.github/workflows"</span>, <span class="pl-s">"datasette-foo/.github/workflows/publish.yml"</span>, <span class="pl-s">"datasette-foo/.github/workflows/test.yml"</span>, <span class="pl-s">"datasette-foo/.gitignore"</span>, <span class="pl-s">"datasette-foo/datasette_foo"</span>, <span class="pl-s">"datasette-foo/datasette_foo/__init__.py"</span>, <span class="pl-s">"datasette-foo/datasette_foo/static"</span>, <span class="pl-s">"datasette-foo/datasette_foo/templates"</span>, <span class="pl-s">"datasette-foo/README.md"</span>, <span class="pl-s">"datasette-foo/setup.py"</span>, <span class="pl-s">"datasette-foo/tests"</span>, <span class="pl-s">"datasette-foo/tests/test_foo.py"</span>, } <span class="pl-s1">setup_py</span> <span class="pl-c1">=</span> (<span class="pl-s1">tmpdir</span> <span class="pl-c1">/</span> <span class="pl-s">"datasette-foo"</span> <span class="pl-c1">/</span> <span class="pl-s">"setup.py"</span>).<span class="pl-en">read_text</span>(<span class="pl-s">"utf-8"</span>) <span class="pl-k">assert</span> ( <span class="pl-s">'package_data={<span class="pl-cce">\n</span> "datasette_foo": ["static/*", "templates/*"]<span class="pl-cce">\n</span> }'</span> ) <span class="pl-c1">in</span> <span class="pl-s1">setup_py</span> <span class="pl-k">def</span> <span class="pl-en">paths</span>(<span class="pl-s1">directory</span>): <span class="pl-s1">paths</span> <span class="pl-c1">=</span> <span class="pl-en">list</span>(<span class="pl-s1">pathlib</span>.<span class="pl-v">Path</span>(<span class="pl-s1">directory</span>).<span class="pl-en">glob</span>(<span class="pl-s">"**/*"</span>)) <span class="pl-s1">paths</span> <span class="pl-c1">=</span> [<span class="pl-s1">r</span>.<span class="pl-en">relative_to</span>(<span class="pl-s1">directory</span>) <span class="pl-k">for</span> <span class="pl-s1">r</span> <span class="pl-c1">in</span> <span class="pl-s1">paths</span>] <span class="pl-k">return</span> {<span class="pl-en">str</span>(<span class="pl-s1">f</span>) <span class="pl-k">for</span> <span class="pl-s1">f</span> <span class="pl-c1">in</span> <span class="pl-s1">paths</span> <span class="pl-k">if</span> <span class="pl-en">str</span>(<span class="pl-s1">f</span>) <span class="pl-c1">!=</span> <span class="pl-s">"."</span>}</pre></div> <Binary: 63,953 bytes> 2021-01-27T15:50:02-08:00 2021-01-27T23:50:02+00:00 2021-01-27T15:58:29-08:00 2021-01-27T23:58:29+00:00 d71fe0d87b578550b41660a4de61ee0f pytest-for-cookiecutter
Powered by Datasette · How this site works · Code of conduct