Repository: tox-dev/tox

Issue:
change_dir fails if directory does not exist
        I found the issue I think: `change_dir` says that the directory is created if it doesn't exist, but that does not seem to be the case:

> Change to this working directory when executing the test command. If the directory does not exist yet, it will be created (required for Windows to be able to execute any command).

with `change_dir = foo` the tests don't run and show the error above.

When I do `mkdir foo` myself before, it works.

_Originally posted by @maxnoe in https://github.com/tox-dev/tox/issues/2612#issuecomment-1341515799_
      

Discussion:

Patch:
diff --git a/docs/changelog/2620.bugfix.rst b/docs/changelog/2620.bugfix.rst
new file mode 100644
index 00000000..ba4c5bd5
--- /dev/null
+++ b/docs/changelog/2620.bugfix.rst
@@ -0,0 +1,1 @@
+Ensure :ref:`change_dir` is created if does not exist before executing :ref:`commands` - by :user:`gaborbernat`.
diff --git a/src/tox/session/cmd/run/single.py b/src/tox/session/cmd/run/single.py
index 9cc3e45e..9ef909d1 100644
--- a/src/tox/session/cmd/run/single.py
+++ b/src/tox/session/cmd/run/single.py
@@ -71,6 +71,7 @@ def run_commands(tox_env: RunToxEnv, no_test: bool) -> tuple[int, list[Outcome]]
         from tox.plugin.manager import MANAGER  # importing this here to avoid circular import
 
         chdir: Path = tox_env.conf["change_dir"]
+        chdir.mkdir(exist_ok=True, parents=True)
         ignore_errors: bool = tox_env.conf["ignore_errors"]
         MANAGER.tox_before_run_commands(tox_env)
         status_pre, status_main, status_post = -1, -1, -1


Test patch:
diff --git a/tests/tox_env/test_tox_env_api.py b/tests/tox_env/test_tox_env_api.py
index c5542dbc..2c467bb6 100644
--- a/tests/tox_env/test_tox_env_api.py
+++ b/tests/tox_env/test_tox_env_api.py
@@ -86,3 +86,10 @@ def test_tox_env_pass_env_match_ignore_case(char: str, glob: str) -> None:
     with patch("os.environ", {"A1": "1", "a2": "2", "A2": "3", "B": "4"}):
         env = ToxEnv._load_pass_env([f"{char}{glob}"])
     assert env == {"A1": "1", "a2": "2", "A2": "3"}
+
+
+def test_change_dir_is_created_if_not_exist(tox_project: ToxProjectCreator) -> None:
+    prj = tox_project({"tox.ini": "[testenv]\npackage=skip\nchange_dir=a{/}b\ncommands=python --version"})
+    result_first = prj.run("r")
+    result_first.assert_success()
+    assert (prj.path / "a" / "b").exists()