mirror of
https://github.com/unclebob/mutator.git
synced 2026-11-06 18:23:50 +00:00
Run Python tests with the project's virtualenv.
Mutator's interpreter does not have the project installed, so the baseline failed before any mutant ran.
This commit is contained in:
@@ -110,7 +110,7 @@ The baseline command has to pass before any mutant runs. A mutant's timeout is t
|
||||
| Go | `go test -count=1` of the file's package | nearest `go.mod` |
|
||||
| TypeScript | `npm test` | nearest `package.json` |
|
||||
| Rust | `cargo test` | nearest `Cargo.toml` |
|
||||
| Python | `python -m pytest`, or `unittest discover` | nearest project file |
|
||||
| Python | the project's `.venv` or `venv` Python running `pytest`, or `unittest discover` | nearest project file |
|
||||
|
||||
Coverage is generated with crapper's commands unless `--use-existing-coverage` or `--no-coverage` is set. A file missing from the report is treated as uncovered, and the run says so.
|
||||
|
||||
|
||||
+17
-2
@@ -128,7 +128,22 @@ def _clojure_command(directory: Path) -> str:
|
||||
return "clj -M:test"
|
||||
|
||||
|
||||
def _project_interpreter(directory: Path) -> str:
|
||||
"""The project's virtualenv, or this process when the project has none.
|
||||
|
||||
The path stays absolute and the symlink is left in place. A worker does
|
||||
not link ``.venv``, and resolving ``bin/python`` would leave the virtualenv.
|
||||
"""
|
||||
|
||||
for name in (".venv", "venv"):
|
||||
candidate = (directory / name / "bin" / "python").absolute()
|
||||
if candidate.is_file() and os.access(candidate, os.X_OK):
|
||||
return str(candidate)
|
||||
return sys.executable
|
||||
|
||||
|
||||
def _python_command(directory: Path) -> str:
|
||||
interpreter = _project_interpreter(directory)
|
||||
pyproject = _read(directory / "pyproject.toml")
|
||||
if (
|
||||
(directory / "pytest.ini").is_file()
|
||||
@@ -136,8 +151,8 @@ def _python_command(directory: Path) -> str:
|
||||
or "pytest" in pyproject
|
||||
or (directory / "setup.cfg").is_file() and "pytest" in _read(directory / "setup.cfg")
|
||||
):
|
||||
return f"{sys.executable} -m pytest"
|
||||
return f"{sys.executable} -m unittest discover"
|
||||
return f"{interpreter} -m pytest"
|
||||
return f"{interpreter} -m unittest discover"
|
||||
|
||||
|
||||
def test_plan(root: Path, source: Path, language: str, override: str | None) -> tuple[str, Path]:
|
||||
|
||||
@@ -44,6 +44,51 @@ def test_clojure_commands(tmp_path):
|
||||
assert _clojure_command(plain) == "clj -M:test"
|
||||
|
||||
|
||||
def _executable(path):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text("#!/bin/sh\n", encoding="utf-8")
|
||||
path.chmod(0o755)
|
||||
|
||||
|
||||
def test_python_command_uses_an_absolute_project_interpreter(tmp_path):
|
||||
project = tmp_path / "proj"
|
||||
dot = project / ".venv" / "bin" / "python"
|
||||
_executable(dot)
|
||||
(project / "pytest.ini").write_text("[pytest]\n", encoding="utf-8")
|
||||
assert _python_command(project) == f"{dot.absolute()} -m pytest"
|
||||
|
||||
other = tmp_path / "other"
|
||||
plain = other / "venv" / "bin" / "python"
|
||||
_executable(plain)
|
||||
assert _python_command(other) == f"{plain.absolute()} -m unittest discover"
|
||||
|
||||
_executable(other / ".venv" / "bin" / "python")
|
||||
assert _python_command(other) == f"{(other / '.venv' / 'bin' / 'python').absolute()} -m unittest discover"
|
||||
|
||||
|
||||
def test_python_command_keeps_the_virtualenv_symlink(tmp_path):
|
||||
project = tmp_path / "proj"
|
||||
target = project / "real-python"
|
||||
_executable(target)
|
||||
link = project / ".venv" / "bin" / "python"
|
||||
link.parent.mkdir(parents=True)
|
||||
link.symlink_to(target)
|
||||
(project / "pytest.ini").write_text("[pytest]\n", encoding="utf-8")
|
||||
assert _python_command(project) == f"{link.absolute()} -m pytest"
|
||||
|
||||
|
||||
def test_python_command_falls_back_when_the_virtualenv_cannot_run(tmp_path):
|
||||
project = tmp_path / "proj"
|
||||
binary = project / ".venv" / "bin" / "python"
|
||||
binary.parent.mkdir(parents=True)
|
||||
binary.write_text("", encoding="utf-8")
|
||||
assert _python_command(project) == f"{sys.executable} -m unittest discover"
|
||||
|
||||
missing = tmp_path / "missing"
|
||||
missing.mkdir()
|
||||
assert _python_command(missing) == f"{sys.executable} -m unittest discover"
|
||||
|
||||
|
||||
def test_python_commands(tmp_path):
|
||||
pytest_dir = tmp_path / "py"
|
||||
pytest_dir.mkdir()
|
||||
|
||||
Reference in New Issue
Block a user