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:
Levon Saldamli 2024-03-09 07:51:52 +01:00 committed by GitHub
parent 2ccc73be9a
commit 9033d4d3ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 66 additions and 1 deletions

1
.gitignore vendored
View File

@ -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/

View File

@ -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

View File

@ -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.

View File

@ -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
-------------------------------------------------------------- --------------------------------------------------------------

View File

@ -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.

View File

@ -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:

View File

@ -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")