Skip to content

Commit 633c494

Browse files
levsabluetechnicoddemus
authored andcommitted
Parse args from file (pytest-dev#12085)
Co-authored-by: Ran Benita <[email protected]> Co-authored-by: Bruno Oliveira <[email protected]>
1 parent 7c89fc2 commit 633c494

File tree

7 files changed

+66
-1
lines changed

7 files changed

+66
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ coverage.xml
5151
.settings
5252
.vscode
5353
__pycache__/
54+
.python-version
5455

5556
# generated by pip
5657
pip-wheel-metadata/

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ Kyle Altendorf
235235
Lawrence Mitchell
236236
Lee Kamentsky
237237
Lev Maximov
238+
Levon Saldamli
238239
Lewis Cowles
239240
Llandy Riveron Del Risco
240241
Loic Esteve

changelog/11871.feature.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

doc/en/how-to/usage.rst

+24-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ in the current directory and its subdirectories. More generally, pytest follows
1717
Specifying which tests to run
1818
------------------------------
1919

20-
Pytest supports several ways to run and select tests from the command-line.
20+
Pytest supports several ways to run and select tests from the command-line or from a file
21+
(see below for :ref:`reading arguments from file <args-from-file>`).
2122

2223
**Run tests in a module**
2324

@@ -91,6 +92,28 @@ For more information see :ref:`marks <mark>`.
9192
9293
This will import ``pkg.testing`` and use its filesystem location to find and run tests from.
9394

95+
.. _args-from-file:
96+
97+
**Read arguments from file**
98+
99+
.. versionadded:: 8.2
100+
101+
All of the above can be read from a file using the ``@`` prefix:
102+
103+
.. code-block:: bash
104+
105+
pytest @tests_to_run.txt
106+
107+
where ``tests_to_run.txt`` contains an entry per line, e.g.:
108+
109+
.. code-block:: text
110+
111+
tests/test_file.py
112+
tests/test_mod.py::test_func[x1,y2]
113+
tests/test_mod.py::TestClass
114+
-m slow
115+
116+
This file can also be generated using ``pytest --collect-only -q`` and modified as needed.
94117

95118
Getting help on version, option names, environment variables
96119
--------------------------------------------------------------

src/_pytest/config/argparsing.py

+1
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ def __init__(
415415
add_help=False,
416416
formatter_class=DropShorterLongHelpFormatter,
417417
allow_abbrev=False,
418+
fromfile_prefix_chars="@",
418419
)
419420
# extra_info is a dict of (param -> value) to display if there's
420421
# an usage error to provide more contextual information to the user.

testing/acceptance_test.py

+27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import dataclasses
33
import importlib.metadata
44
import os
5+
from pathlib import Path
56
import subprocess
67
import sys
78
import types
@@ -541,6 +542,32 @@ def test_foo(data):
541542
res = pytester.runpytest(p)
542543
res.assert_outcomes(passed=3)
543544

545+
# Warning ignore because of:
546+
# https://github.com/python/cpython/issues/85308
547+
# Can be removed once Python<3.12 support is dropped.
548+
@pytest.mark.filterwarnings("ignore:'encoding' argument not specified")
549+
def test_command_line_args_from_file(
550+
self, pytester: Pytester, tmp_path: Path
551+
) -> None:
552+
pytester.makepyfile(
553+
test_file="""
554+
import pytest
555+
556+
class TestClass:
557+
@pytest.mark.parametrize("a", ["x","y"])
558+
def test_func(self, a):
559+
pass
560+
"""
561+
)
562+
tests = [
563+
"test_file.py::TestClass::test_func[x]",
564+
"test_file.py::TestClass::test_func[y]",
565+
"-q",
566+
]
567+
args_file = pytester.maketxtfile(tests="\n".join(tests))
568+
result = pytester.runpytest(f"@{args_file}")
569+
result.assert_outcomes(failed=0, passed=2)
570+
544571

545572
class TestInvocationVariants:
546573
def test_earlyinit(self, pytester: Pytester) -> None:

testing/test_parseopt.py

+11
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@ def test_parse2(self, parser: parseopt.Parser) -> None:
125125
args = parser.parse([Path(".")])
126126
assert getattr(args, parseopt.FILE_OR_DIR)[0] == "."
127127

128+
# Warning ignore because of:
129+
# https://github.com/python/cpython/issues/85308
130+
# Can be removed once Python<3.12 support is dropped.
131+
@pytest.mark.filterwarnings("ignore:'encoding' argument not specified")
132+
def test_parse_from_file(self, parser: parseopt.Parser, tmp_path: Path) -> None:
133+
tests = [".", "some.py::Test::test_method[param0]", "other/test_file.py"]
134+
args_file = tmp_path / "tests.txt"
135+
args_file.write_text("\n".join(tests), encoding="utf-8")
136+
args = parser.parse([f"@{args_file.absolute()}"])
137+
assert getattr(args, parseopt.FILE_OR_DIR) == tests
138+
128139
def test_parse_known_args(self, parser: parseopt.Parser) -> None:
129140
parser.parse_known_args([Path(".")])
130141
parser.addoption("--hello", action="store_true")

0 commit comments

Comments
 (0)