21 May 2024 Leave a comment Tech-Help
When working with pytest
and the parametrize
decorator, there are occasions where you may want to run just a single test case out of a set of parameterized tests. This can be especially useful when debugging or focusing on a specific scenario. Below, we outline effective methods to achieve this.
Using the -k Flag
One straightforward method is to use the -k
flag. This flag allows you to filter tests that match a specified string expression. Pytest names each test case using the convention:
test_name['-' separated test inputs]
For example, if you have a test named test_my_feature
with parameters value_1
and value_2
, you can run this particular test case by using the following command:
pytest -k 'test_my_feature[value_1-value_2]'
Alternatively, you can use:
pytest -k test_my_feature\\[value_1-value_2\\]
Note that you need to escape the square brackets.
Using –collect-only
Another method involves using the --collect-only
flag to list all tests without executing them. This can help you identify the exact name of the test you wish to run. Here’s how:
pytest --collect-only -q
After identifying the test name, you can run the specific test by using:
pytest test_file_name.py::test_my_feature[value_1-value_2]
Be sure to use quotes if there are spaces in the identifier.
Limiting the Number of Test Runs
If you have parameterized tests that take a long time to run, you can limit the number of test runs by adding custom options to your conftest.py
file. This approach can be particularly useful for running a subset of tests for quick feedback. Add the following code to your conftest.py
:
def pytest_addoption(parser):
parser.addoption(
"--limit",
action="store",
default=-1,
type=int,
help="Maximum number of permutations of parametrized tests to run",
)
def pytest_collection_modifyitems(session, config, items):
def get_base_name(test_name):
try:
return test_name[: test_name.index("[")]
except ValueError:
return test_name
limit = config.getoption("--limit")
if limit >= 0:
tests_by_name = {item.name: item for item in items}
test_base_names = set(get_base_name(name) for name in tests_by_name.keys())
tests_to_run = []
for base_name in test_base_names:
to_skip = [t for n, t in tests_by_name.items() if base_name in n][limit:]
for t in to_skip:
t.add_marker("skip")
Conclusion
Running a single test case in a set of parameterized tests is straightforward with the right commands and configurations. By using the -k
flag, the --collect-only
option, or limiting the number of test runs, you can efficiently focus on specific test scenarios.
For those developing mobile applications, our product Repeato offers a no-code test automation tool for iOS and Android. It allows you to create, run, and maintain automated tests for your apps quickly and efficiently. Whether you’re running tests on mobile or preparing for explicit web testing support coming later this summer, Repeato provides an intuitive interface and advanced scripting capabilities to meet your testing needs.