diff --git a/pyproject.toml b/pyproject.toml index c4f7901..f524db1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,8 @@ lint.per-file-ignores."tests/**/*.py" = [ "implicit-namespace-package", # no implicit namespace "magic-value-comparison", # Magic value used in comparison, consider replacing with a constant variable "subprocess-without-shell-equals-true", # `subprocess` call: check for execution of untrusted input + "too-many-arguments", # pytest injects fixtures and parameters as arguments + "too-many-positional-arguments", # pytest injects fixtures and parameters as arguments ] lint.isort = { known-first-party = [ "pytest_env", diff --git a/tests/conftest.py b/tests/conftest.py index fd9d35f..cc142dd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,15 @@ from __future__ import annotations +from pathlib import Path +from typing import Final + +import pytest + pytest_plugins = ["pytester"] + + +@pytest.fixture +def env_test_template() -> str: + template: Final[Path] = Path(__file__).with_name("template.py") + # Execute the original template so coverage still records its assertions. + return f"from runpy import run_path\n\ntest_env = run_path({str(template)!r})['test_env']\n" diff --git a/tests/test_env.py b/tests/test_env.py index eb883b5..d7b8795 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -119,13 +119,14 @@ ) def test_env_via_pytest( pytester: pytest.Pytester, + env_test_template: str, env: dict[str, str], ini: str, expected_env: dict[str, str], request: pytest.FixtureRequest, ) -> None: test_name = re.sub(r"\W|^(?=\d)", "_", request.node.callspec.id).lower() - (pytester.path / f"test_{test_name}.py").symlink_to(Path(__file__).parent / "template.py") + (pytester.path / f"test_{test_name}.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pytest.ini").write_text(ini, encoding="utf-8") new_env = { @@ -281,8 +282,9 @@ def test_env_via_pytest( ), ], ) -def test_env_via_toml( # ruff:ignore[too-many-arguments, too-many-positional-arguments] +def test_env_via_toml( pytester: pytest.Pytester, + env_test_template: str, env: dict[str, str], pyproject_toml: str, pytest_toml: str, @@ -306,7 +308,7 @@ def test_env_via_toml( # ruff:ignore[too-many-arguments, too-many-positional-ar if ini: (pytester.path / "pytest.ini").write_text(ini, encoding="utf-8") - (test_dir / f"test_{test_name}.py").symlink_to(Path(__file__).parent / "template.py") + (test_dir / f"test_{test_name}.py").write_text(env_test_template, encoding="utf-8") new_env = { **env, @@ -478,8 +480,9 @@ def test_env_via_toml( # ruff:ignore[too-many-arguments, too-many-positional-ar ), ], ) -def test_env_via_env_file( # ruff:ignore[too-many-arguments, too-many-positional-arguments] +def test_env_via_env_file( pytester: pytest.Pytester, + env_test_template: str, env: dict[str, str], env_file_content: str, config: str, @@ -488,7 +491,7 @@ def test_env_via_env_file( # ruff:ignore[too-many-arguments, too-many-positiona request: pytest.FixtureRequest, ) -> None: test_name = re.sub(r"\W|^(?=\d)", "_", request.node.callspec.id).lower() - (pytester.path / f"test_{test_name}.py").symlink_to(Path(__file__).parent / "template.py") + (pytester.path / f"test_{test_name}.py").write_text(env_test_template, encoding="utf-8") if env_file_content: (pytester.path / ".env").write_text(env_file_content, encoding="utf-8") config_file_names = {"pyproject": "pyproject.toml", "pytest.toml": "pytest.toml", "ini": "pytest.ini"} @@ -623,15 +626,16 @@ def test_env_via_pyproject_toml_bad(pytester: pytest.Pytester, toml_name: str) - ), ], ) -def test_envfile_cli( # ruff:ignore[too-many-arguments, too-many-positional-arguments] +def test_envfile_cli( pytester: pytest.Pytester, + env_test_template: str, env_file_content: str | None, cli_file_content: str, config: str | None, cli_arg: str, expected_env: dict[str, str], ) -> None: - (pytester.path / "test_cli.py").symlink_to(Path(__file__).parent / "template.py") + (pytester.path / "test_cli.py").write_text(env_test_template, encoding="utf-8") if env_file_content: (pytester.path / ".env").write_text(env_file_content, encoding="utf-8") @@ -651,8 +655,8 @@ def test_envfile_cli( # ruff:ignore[too-many-arguments, too-many-positional-arg result.assert_outcomes(passed=1) -def test_envfile_cli_skip_if_set(pytester: pytest.Pytester) -> None: - (pytester.path / "test_cli_skip.py").symlink_to(Path(__file__).parent / "template.py") +def test_envfile_cli_skip_if_set(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_cli_skip.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "cli.env").write_text("MAGIC=from_cli", encoding="utf-8") (pytester.path / "pyproject.toml").write_text( dedent("""\ diff --git a/tests/test_verbose.py b/tests/test_verbose.py index 918061a..eda2ec9 100644 --- a/tests/test_verbose.py +++ b/tests/test_verbose.py @@ -1,7 +1,6 @@ from __future__ import annotations import os -from pathlib import Path from textwrap import dedent from typing import TYPE_CHECKING from unittest import mock @@ -10,8 +9,8 @@ import pytest -def test_verbose_shows_set_from_ini(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_set_from_ini(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pytest.ini").write_text("[pytest]\nenv = MAGIC=alpha", encoding="utf-8") new_env = { @@ -26,8 +25,10 @@ def test_verbose_shows_set_from_ini(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*pytest-env:*", "*SET*MAGIC=alpha*(from*pytest.ini*"]) -def test_verbose_shows_ini_source_when_pyproject_lacks_pytest_env(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_ini_source_when_pyproject_lacks_pytest_env( + pytester: pytest.Pytester, env_test_template: str +) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pyproject.toml").write_text( dedent("""\ [build-system] @@ -50,8 +51,8 @@ def test_verbose_shows_ini_source_when_pyproject_lacks_pytest_env(pytester: pyte result.stdout.fnmatch_lines(["*SET*MAGIC=alpha*(from*pytest.ini*"]) -def test_verbose_shows_set_from_toml(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_set_from_toml(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pyproject.toml").write_text( '[tool.pytest_env]\nMY_VAR = "hello"', encoding="utf-8", @@ -69,8 +70,8 @@ def test_verbose_shows_set_from_toml(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*pytest-env:*", "*SET*MY_VAR=hello*(from*pyproject.toml*"]) -def test_verbose_shows_set_from_env_file(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_set_from_env_file(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / ".env").write_text("FROM_FILE=value", encoding="utf-8") (pytester.path / "pyproject.toml").write_text( '[tool.pytest_env]\nenv_files = [".env"]', @@ -89,8 +90,8 @@ def test_verbose_shows_set_from_env_file(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*SET*FROM_FILE=value*(from*.env*"]) -def test_verbose_shows_skip_from_env_file(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_skip_from_env_file(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / ".env").write_text("FROM_FILE=value", encoding="utf-8") (pytester.path / "pyproject.toml").write_text( dedent("""\ @@ -114,8 +115,8 @@ def test_verbose_shows_skip_from_env_file(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*SKIP*FROM_FILE=original*(from*.env*"]) -def test_verbose_shows_skip(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_skip(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pytest.ini").write_text("[pytest]\nenv = D:EXISTING=new", encoding="utf-8") new_env = { @@ -131,8 +132,8 @@ def test_verbose_shows_skip(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*SKIP*EXISTING=original*"]) -def test_verbose_shows_unset(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_unset(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pytest.ini").write_text("[pytest]\nenv = U:TO_REMOVE", encoding="utf-8") new_env = { @@ -148,8 +149,8 @@ def test_verbose_shows_unset(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*UNSET*TO_REMOVE*"]) -def test_verbose_shows_transform(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_shows_transform(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pyproject.toml").write_text( dedent("""\ [tool.pytest_env] @@ -171,8 +172,8 @@ def test_verbose_shows_transform(pytester: pytest.Pytester) -> None: result.stdout.fnmatch_lines(["*SET*GREETING=hello_world*"]) -def test_no_verbose_output_without_flag(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_no_verbose_output_without_flag(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / "pytest.ini").write_text("[pytest]\nenv = MAGIC=alpha", encoding="utf-8") new_env = { @@ -187,8 +188,8 @@ def test_no_verbose_output_without_flag(pytester: pytest.Pytester) -> None: result.stdout.no_fnmatch_line("*pytest-env:*") -def test_verbose_multiple_sources(pytester: pytest.Pytester) -> None: - (pytester.path / "test_it.py").symlink_to(Path(__file__).parent / "template.py") +def test_verbose_multiple_sources(pytester: pytest.Pytester, env_test_template: str) -> None: + (pytester.path / "test_it.py").write_text(env_test_template, encoding="utf-8") (pytester.path / ".env").write_text("FROM_FILE=file_val", encoding="utf-8") (pytester.path / "pyproject.toml").write_text( dedent("""\