Current section

Files

Jump to
snakepit lib mix tasks snakepit.python_test.ex
Raw

lib/mix/tasks/snakepit.python_test.ex

defmodule Mix.Tasks.Snakepit.PythonTest do
@shortdoc "Bootstrap and run Snakepit Python tests"
@moduledoc """
Bootstraps the Snakepit Python environment and runs the Python test suite.
Usage:
mix snakepit.python_test
mix snakepit.python_test -- --maxfail=1
Options:
* `--no-bootstrap` - Skip `mix snakepit.setup`
"""
use Mix.Task
@impl true
def run(args) do
{opts, pytest_args, _} =
OptionParser.parse(args, strict: [no_bootstrap: :boolean])
unless opts[:no_bootstrap] do
Mix.Task.run("snakepit.setup")
end
{python, env, project_root} = resolve_python_env()
tests_dir = Path.join(project_root, "priv/python/tests")
cmd_args = ["-m", "pytest", tests_dir] ++ pytest_args
{output, status} =
System.cmd(python, cmd_args,
env: env,
cd: project_root,
stderr_to_stdout: true
)
if output != "" do
Mix.shell().info(output)
end
if status != 0 do
Mix.raise("Python tests failed with exit code #{status}")
end
end
defp resolve_python_env do
project_root = File.cwd!()
priv_python = Path.join(project_root, "priv/python")
venv_python = Path.join(project_root, ".venv/bin/python")
python =
System.get_env("SNAKEPIT_TEST_PYTHON") ||
if(File.exists?(venv_python), do: venv_python, else: nil) ||
Snakepit.PythonRuntime.executable_path() ||
System.find_executable("python3") ||
System.find_executable("python") ||
Mix.raise(
"Python executable not found; run mix snakepit.setup or set SNAKEPIT_TEST_PYTHON"
)
env = [{"PYTHONPATH", priv_python}]
{python, env, project_root}
end
end