Parse args from file (#12085)
Co-authored-by: Ran Benita <ran@unusedvar.com> Co-authored-by: Bruno Oliveira <bruno@soliv.dev>
This commit is contained in:
parent
2ccc73be9a
commit
9033d4d3ff
|
@ -51,6 +51,7 @@ coverage.xml
|
||||||
.settings
|
.settings
|
||||||
.vscode
|
.vscode
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
.python-version
|
||||||
|
|
||||||
# generated by pip
|
# generated by pip
|
||||||
pip-wheel-metadata/
|
pip-wheel-metadata/
|
||||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -235,6 +235,7 @@ Kyle Altendorf
|
||||||
Lawrence Mitchell
|
Lawrence Mitchell
|
||||||
Lee Kamentsky
|
Lee Kamentsky
|
||||||
Lev Maximov
|
Lev Maximov
|
||||||
|
Levon Saldamli
|
||||||
Lewis Cowles
|
Lewis Cowles
|
||||||
Llandy Riveron Del Risco
|
Llandy Riveron Del Risco
|
||||||
Loic Esteve
|
Loic Esteve
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added support for reading command line arguments from a file using the prefix character ``@``, like e.g.: ``pytest @tests.txt``. The file must have one argument per line.
|
|
@ -17,7 +17,8 @@ in the current directory and its subdirectories. More generally, pytest follows
|
||||||
Specifying which tests to run
|
Specifying which tests to run
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
Pytest supports several ways to run and select tests from the command-line.
|
Pytest supports several ways to run and select tests from the command-line or from a file
|
||||||
|
(see below for :ref:`reading arguments from file <args-from-file>`).
|
||||||
|
|
||||||
**Run tests in a module**
|
**Run tests in a module**
|
||||||
|
|
||||||
|
@ -91,6 +92,28 @@ For more information see :ref:`marks <mark>`.
|
||||||
|
|
||||||
This will import ``pkg.testing`` and use its filesystem location to find and run tests from.
|
This will import ``pkg.testing`` and use its filesystem location to find and run tests from.
|
||||||
|
|
||||||
|
.. _args-from-file:
|
||||||
|
|
||||||
|
**Read arguments from file**
|
||||||
|
|
||||||
|
.. versionadded:: 8.2
|
||||||
|
|
||||||
|
All of the above can be read from a file using the ``@`` prefix:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
pytest @tests_to_run.txt
|
||||||
|
|
||||||
|
where ``tests_to_run.txt`` contains an entry per line, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
tests/test_file.py
|
||||||
|
tests/test_mod.py::test_func[x1,y2]
|
||||||
|
tests/test_mod.py::TestClass
|
||||||
|
-m slow
|
||||||
|
|
||||||
|
This file can also be generated using ``pytest --collect-only -q`` and modified as needed.
|
||||||
|
|
||||||
Getting help on version, option names, environment variables
|
Getting help on version, option names, environment variables
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
|
@ -415,6 +415,7 @@ class MyOptionParser(argparse.ArgumentParser):
|
||||||
add_help=False,
|
add_help=False,
|
||||||
formatter_class=DropShorterLongHelpFormatter,
|
formatter_class=DropShorterLongHelpFormatter,
|
||||||
allow_abbrev=False,
|
allow_abbrev=False,
|
||||||
|
fromfile_prefix_chars="@",
|
||||||
)
|
)
|
||||||
# extra_info is a dict of (param -> value) to display if there's
|
# extra_info is a dict of (param -> value) to display if there's
|
||||||
# an usage error to provide more contextual information to the user.
|
# an usage error to provide more contextual information to the user.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
@ -541,6 +542,32 @@ class TestGeneralUsage:
|
||||||
res = pytester.runpytest(p)
|
res = pytester.runpytest(p)
|
||||||
res.assert_outcomes(passed=3)
|
res.assert_outcomes(passed=3)
|
||||||
|
|
||||||
|
# Warning ignore because of:
|
||||||
|
# https://github.com/python/cpython/issues/85308
|
||||||
|
# Can be removed once Python<3.12 support is dropped.
|
||||||
|
@pytest.mark.filterwarnings("ignore:'encoding' argument not specified")
|
||||||
|
def test_command_line_args_from_file(
|
||||||
|
self, pytester: Pytester, tmp_path: Path
|
||||||
|
) -> None:
|
||||||
|
pytester.makepyfile(
|
||||||
|
test_file="""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
class TestClass:
|
||||||
|
@pytest.mark.parametrize("a", ["x","y"])
|
||||||
|
def test_func(self, a):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
tests = [
|
||||||
|
"test_file.py::TestClass::test_func[x]",
|
||||||
|
"test_file.py::TestClass::test_func[y]",
|
||||||
|
"-q",
|
||||||
|
]
|
||||||
|
args_file = pytester.maketxtfile(tests="\n".join(tests))
|
||||||
|
result = pytester.runpytest(f"@{args_file}")
|
||||||
|
result.assert_outcomes(failed=0, passed=2)
|
||||||
|
|
||||||
|
|
||||||
class TestInvocationVariants:
|
class TestInvocationVariants:
|
||||||
def test_earlyinit(self, pytester: Pytester) -> None:
|
def test_earlyinit(self, pytester: Pytester) -> None:
|
||||||
|
|
|
@ -125,6 +125,17 @@ class TestParser:
|
||||||
args = parser.parse([Path(".")])
|
args = parser.parse([Path(".")])
|
||||||
assert getattr(args, parseopt.FILE_OR_DIR)[0] == "."
|
assert getattr(args, parseopt.FILE_OR_DIR)[0] == "."
|
||||||
|
|
||||||
|
# Warning ignore because of:
|
||||||
|
# https://github.com/python/cpython/issues/85308
|
||||||
|
# Can be removed once Python<3.12 support is dropped.
|
||||||
|
@pytest.mark.filterwarnings("ignore:'encoding' argument not specified")
|
||||||
|
def test_parse_from_file(self, parser: parseopt.Parser, tmp_path: Path) -> None:
|
||||||
|
tests = [".", "some.py::Test::test_method[param0]", "other/test_file.py"]
|
||||||
|
args_file = tmp_path / "tests.txt"
|
||||||
|
args_file.write_text("\n".join(tests), encoding="utf-8")
|
||||||
|
args = parser.parse([f"@{args_file.absolute()}"])
|
||||||
|
assert getattr(args, parseopt.FILE_OR_DIR) == tests
|
||||||
|
|
||||||
def test_parse_known_args(self, parser: parseopt.Parser) -> None:
|
def test_parse_known_args(self, parser: parseopt.Parser) -> None:
|
||||||
parser.parse_known_args([Path(".")])
|
parser.parse_known_args([Path(".")])
|
||||||
parser.addoption("--hello", action="store_true")
|
parser.addoption("--hello", action="store_true")
|
||||||
|
|
Loading…
Reference in New Issue