Skip to content

Commit 37de175

Browse files
committed
Rewrite tests for venv install as test cases
Each test case now defines and writes its own requirement files and checks the full content, instead of just checking for common markers.
1 parent 68a72db commit 37de175

File tree

2 files changed

+161
-17
lines changed

2 files changed

+161
-17
lines changed

tests/test_venv_install.py

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,76 @@
1-
import os
1+
import re
22
from pathlib import Path
33

44
import pytest
5+
from pytest_cases import parametrize_with_cases
56

6-
from tests.helpers import RequirementFiles, run_command
7+
from tests.helpers import run_command
8+
from tests.test_venv_install_cases import CasesVenvInstallDevRequirementstxt, CasesVenvInstallRequirementstxt
9+
10+
_package_regex = re.compile(r"^([a-zA-Z0-9_-]+)\b")
11+
12+
13+
@pytest.mark.order(after="test_venv_activate.py::test_venv_activate")
14+
@pytest.mark.parametrize("command_arg", ["", "requirements.txt"])
15+
@parametrize_with_cases(argnames=["files"], cases=CasesVenvInstallRequirementstxt)
16+
def test_venv_install_requirements_txt(
17+
command_arg: str,
18+
files: dict[str, str],
19+
tmp_path: Path,
20+
capfd: pytest.CaptureFixture,
21+
):
22+
(tmp_path / "requirements.txt").write_text(files["requirements.txt"])
23+
24+
# Install the requirements
25+
run_command(f"venv install {command_arg} --skip-lock", cwd=tmp_path, activated=True)
26+
27+
# Check pip install log output
28+
output: str = capfd.readouterr().out
29+
assert "Installing requirements from requirements.txt" in output
30+
31+
installed_line = [line for line in output.splitlines() if line.startswith("Successfully installed")][0]
32+
for requirement in files["requirements.txt"].splitlines():
33+
re_match = _package_regex.match(requirement)
34+
if re_match is None:
35+
raise ValueError(f"Could not extract package name from requirement '{requirement}'")
36+
37+
package_name = re_match.group()
38+
assert package_name in installed_line
739

840

941
@pytest.mark.order(after="test_venv_activate.py::test_venv_activate")
10-
@pytest.mark.parametrize(
11-
"file",
12-
[
13-
"",
14-
"requirements.txt",
15-
"dev-requirements.txt",
16-
"requirements.lock",
17-
"dev-requirements.lock",
18-
],
19-
)
20-
def test_venv_install(file: str, venv_dir: RequirementFiles, create_test_credentials: None):
21-
"""Checks that we can install requirements in an activated environment"""
22-
file_path: str | Path = venv_dir.get(file, file)
23-
24-
run_command(f"venv install {file_path} --skip-lock", activated=True, cwd=venv_dir["base"])
42+
@parametrize_with_cases(argnames=["files"], cases=CasesVenvInstallDevRequirementstxt)
43+
def test_venv_install_dev_requirements_txt(
44+
files: dict[str, str],
45+
tmp_path: Path,
46+
capfd: pytest.CaptureFixture,
47+
):
48+
for file_name, contents in files.items():
49+
(tmp_path / file_name).write_text(contents)
50+
51+
# Install the requirements
52+
run_command("venv install dev-requirements.txt --skip-lock", cwd=tmp_path, activated=True)
53+
54+
# Check pip install log output
55+
output: str = capfd.readouterr().out
56+
assert "Installing requirements from dev-requirements.txt" in output
57+
58+
installed_line = [line for line in output.splitlines() if line.startswith("Successfully installed")][0]
59+
for requirement in [
60+
*files["requirements.txt"].splitlines(),
61+
*files["dev-requirements.txt"].splitlines(),
62+
]:
63+
if requirement.startswith("-r"):
64+
# Skip '-r requirements.txt' line
65+
continue
66+
67+
_check_package_was_installed(requirement=requirement, installed_line=installed_line)
68+
69+
70+
def _check_package_was_installed(requirement: str, installed_line: str) -> None:
71+
re_match = _package_regex.match(requirement)
72+
if re_match is None:
73+
raise ValueError(f"Could not extract package name from requirement '{requirement}'")
74+
75+
package_name = re_match.group()
76+
assert package_name in installed_line

tests/test_venv_install_cases.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
class CasesVenvInstallRequirementstxt:
2+
def case_pypi(self):
3+
requirements = [
4+
"python-json-logger==2.0.7",
5+
]
6+
7+
return {"requirements.txt": "\n".join(requirements)}
8+
9+
def case_git(self):
10+
requirements = [
11+
"python-json-logger @ git+https://github.com/madzak/[email protected]",
12+
]
13+
14+
return {"requirements.txt": "\n".join(requirements)}
15+
16+
def case_git_token(self, create_test_credentials: None):
17+
requirements = ["python-json-logger @ git+https://${TEST_TOKEN}@github.com/madzak/[email protected]"]
18+
19+
return {"requirements.txt": "\n".join(requirements)}
20+
21+
def case_git_user_pass(self, create_test_credentials: None):
22+
requirements = [
23+
"python-json-logger @ git+https://${TEST_USER}:${TEST_PASS}@github.com/madzak/[email protected]"
24+
]
25+
26+
return {"requirements.txt": "\n".join(requirements)}
27+
28+
29+
class CasesVenvInstallDevRequirementstxt:
30+
def case_pypi_dev(self):
31+
requirements = [
32+
"python-json-logger==2.0.7",
33+
]
34+
35+
dev_requirements = [
36+
"-r requirements.txt",
37+
"numpy==1.26.0",
38+
]
39+
40+
files = {
41+
"requirements.txt": "\n".join(requirements),
42+
"dev-requirements.txt": "\n".join(dev_requirements),
43+
}
44+
return files
45+
46+
def case_git_dev(self):
47+
requirements = [
48+
"python-json-logger @ git+https://github.com/madzak/[email protected]",
49+
]
50+
51+
dev_requirements = [
52+
"-r requirements.txt",
53+
"numpy==1.26.0",
54+
]
55+
56+
files = {
57+
"requirements.txt": "\n".join(requirements),
58+
"dev-requirements.txt": "\n".join(dev_requirements),
59+
}
60+
return files
61+
62+
def case_git_token_dev(self, create_test_credentials: None):
63+
requirements = [
64+
"python-json-logger @ git+https://${TEST_TOKEN}@github.com/madzak/[email protected]",
65+
]
66+
67+
dev_requirements = [
68+
"-r requirements.txt",
69+
"numpy==1.26.0",
70+
]
71+
72+
files = {
73+
"requirements.txt": "\n".join(requirements),
74+
"dev-requirements.txt": "\n".join(dev_requirements),
75+
}
76+
return files
77+
78+
def case_git_user_pass_dev(self, create_test_credentials: None):
79+
requirements = [
80+
"python-json-logger @ git+https://${TEST_USER}:${TEST_PASS}@github.com/madzak/[email protected]",
81+
]
82+
83+
dev_requirements = [
84+
"-r requirements.txt",
85+
"numpy==1.26.0",
86+
]
87+
88+
files = {
89+
"requirements.txt": "\n".join(requirements),
90+
"dev-requirements.txt": "\n".join(dev_requirements),
91+
}
92+
return files

0 commit comments

Comments
 (0)