Skip to content

Commit c393f4c

Browse files
committed
automate site generation and testing
1 parent a57be5c commit c393f4c

File tree

6 files changed

+133
-3
lines changed

6 files changed

+133
-3
lines changed

.devcontainer/devcontainer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"charliermarsh.ruff",
3232
"GitHub.vscode-github-actions",
3333
"yzhang.markdown-all-in-one",
34-
"DavidAnson.vscode-markdownlint"
34+
"DavidAnson.vscode-markdownlint",
35+
"ms-vscode.makefile-tools"
3536
]
3637
}
3738
}

.devcontainer/setup.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
python -m pip install --user --upgrade pip
2-
python -m pip install --user pip-tools
2+
python -m venv .venv
3+
source .venv/bin/activate
4+
python -m pip install pip-tools
35
python -m piptools compile --upgrade -o requirements.txt requirements.in
4-
python -m pip install --user -r requirements.txt
6+
python -m pip install -r requirements-dev.txt

.github/workflows/tests.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: PyTest
2+
on:
3+
workflow_call:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
python-version: ["3.9", "3.10", "3.11", "3.12"]
18+
fail-fast: true
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Set up Python ${{ matrix.python-version }}
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
- name: Install dependencies
26+
run: python -m pip install --upgrade pip -r requirements-dev.txt
27+
- name: Run tests
28+
run: python tests/test_template.py

requirements-dev.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
pip-tools
2+
pytest
3+
4+
-r requirements.txt

tests/pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
python_files = test_*.py
3+
python_classes = [A-Z]*Test
4+
python_functions = test_*

tests/test_template.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
""" Test the Cookiecutter template.
2+
3+
A template project is created in a temporary directory, the application is
4+
installed into a self-contained venv environment, and the application test
5+
suite is run.
6+
7+
"""
8+
from cookiecutter.generate import generate_context
9+
from cookiecutter.main import cookiecutter
10+
from pathlib import Path
11+
from shlex import split
12+
from subprocess import run
13+
from venv import create
14+
15+
import pytest
16+
17+
18+
@pytest.fixture(scope="session")
19+
def template() -> Path:
20+
""" The template under test.
21+
22+
"""
23+
return Path(__file__).resolve().parents[1]
24+
25+
26+
@pytest.fixture(scope="module")
27+
def tmpdir(tmp_path_factory) -> Path:
28+
""" Test directory.
29+
30+
"""
31+
return tmp_path_factory.mktemp("test_template")
32+
33+
34+
@pytest.fixture(scope="module")
35+
def context(template) -> dict:
36+
""" Template context for testing.
37+
38+
"""
39+
context = generate_context(template.joinpath("cookiecutter.json"))
40+
context["cookiecutter"].update({
41+
"project_slug": "slugify"
42+
})
43+
return context["cookiecutter"]
44+
45+
46+
@pytest.fixture(scope="module")
47+
def project(tmpdir, template, context) -> Path:
48+
""" Create a test project from the Cookiecutter template.
49+
50+
"""
51+
cookiecutter(str(template), no_input=True, output_dir=tmpdir, extra_context=context)
52+
return tmpdir / context["project_slug"]
53+
54+
55+
@pytest.fixture
56+
def python(tmp_path):
57+
""" Create a Python virtual environment for testing.
58+
59+
"""
60+
venv = tmp_path / ".venv"
61+
create(venv, with_pip=True)
62+
return venv / "bin" / "python"
63+
64+
65+
def test_project(project):
66+
""" Verify that the project was created correctly.
67+
68+
"""
69+
# Just a basic sanity test.
70+
assert len(list(project.iterdir())) == 4
71+
return
72+
73+
74+
@pytest.fixture
75+
def install_render_engine_cli(python):
76+
install_cli = "pip install render_engine[cli]"
77+
install_args = split(f"{python} -m {install_cli}")
78+
install_process = run(install_args)
79+
assert install_process.returncode == 0
80+
81+
82+
def test_site_generation(context, project, python, install_render_engine_cli):
83+
generate_site = "render-engine build app:app"
84+
generate_args = split(generate_site)
85+
generate_process = run(generate_args, cwd=project)
86+
assert generate_process.returncode == 0
87+
88+
89+
# Make the script executable.
90+
91+
if __name__ == "__main__":
92+
raise SystemExit(pytest.main([__file__]))

0 commit comments

Comments
 (0)