diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py
index a6503bf1d..c2057e75d 100644
--- a/src/_pytest/mark/structures.py
+++ b/src/_pytest/mark/structures.py
@@ -165,22 +165,20 @@ class ParameterSet(NamedTuple):
# Check all parameter sets have the correct number of values.
for param in parameters:
if len(param.values) != len(argnames):
+ # Construct a string representation of the expected parameter names
+ expected_argnames = ", ".join(argnames)
+ # Construct a string representation of the provided parameter values
+ provided_values = ", ".join(map(repr, param.values))
msg = (
- '{nodeid}: in "parametrize" the number of names ({names_len}):\n'
- " {names}\n"
- "must be equal to the number of values ({values_len}):\n"
- " {values}"
- )
- fail(
- msg.format(
- nodeid=nodeid,
- values=param.values,
- names=argnames,
- names_len=len(argnames),
- values_len=len(param.values),
- ),
- pytrace=False,
+ f'{nodeid}: \n\n Error in parameterization for test "{func.__name__}".\n '
+ f"The number of specified parameters ({len(argnames)}) "
+ f"does not match the number of provided values ({len(param.values)}): {provided_values}. \n"
+ f" Please ensure that the correct number of parameter names "
+ f"({len(param.values)}) are separated by commas within quotes.\n\n"
+ f'Require more than parameter names: "{expected_argnames}"'
)
+
+ fail(msg, pytrace=False)
else:
# Empty parameter set (likely computed at runtime): create a single
# parameter set with NOTSET values, with the "empty parameter set" mark applied to it.
diff --git a/src/_pytest/python.py b/src/_pytest/python.py
index 5e059f2c4..de23f8026 100644
--- a/src/_pytest/python.py
+++ b/src/_pytest/python.py
@@ -1402,8 +1402,24 @@ class Metafunc:
arg_directness = dict.fromkeys(argnames, "direct")
for arg in indirect:
if arg not in argnames:
+ # Construct a list of valid parameter names
+ valid_params = ", ".join([f'"{name}"' for name in argnames])
+
+ # Construct a string representing the expected number of parameters
+ expected_param_count = len(indirect[0])
+
+ # Construct a string representing the actual number of parameters provided
+ actual_param_count = len(argnames)
+
fail(
- f"In {self.function.__name__}: indirect fixture '{arg}' doesn't exist",
+ f"In function {self.function.__name__}: {argnames} is not a valid parameter. "
+ f"Expected {expected_param_count} sub parameters, "
+ f"but only {actual_param_count} were provided. \n\n"
+ f"Make sure to pass parameter names as strings without quotes, separated by commas, \n "
+ f"e.g., '@pytest.mark.parametrize({valid_params}, )'"
+ f"\n\n"
+ f"Or if multiple parameters are used, separate them by commas. \n "
+ f"e.g., '@pytest.mark.parametrize(\"arg1, arg2\", )'",
pytrace=False,
)
arg_directness[arg] = "indirect"
diff --git a/testing/local_testing/local_test_0.py b/testing/local_testing/local_test_0.py
index 76c079dea..fbc477f15 100644
--- a/testing/local_testing/local_test_0.py
+++ b/testing/local_testing/local_test_0.py
@@ -1,8 +1,8 @@
import pytest
-@pytest.mark.parametrize("arg1,arg2", [(1, 1)])
-def test_parametrization(arg1, arg2):
+@pytest.mark.parametrize("arg1, arg2", [(1, 1)])
+def test_parametrization(arg1: int, arg2: int) -> None:
assert arg1 == arg2
assert arg1 + 1 == arg2 + 1
diff --git a/testing/local_testing/local_test_test.py b/testing/local_testing/local_test_test.py
index 23ac56060..cb1c534bd 100644
--- a/testing/local_testing/local_test_test.py
+++ b/testing/local_testing/local_test_test.py
@@ -9,5 +9,5 @@ result_index = [(1, 2, 3), (-1, 1, 0), (0, 0, 0), (5, -3, 2), (1, 1, 2)]
@pytest.mark.parametrize("a, b,expected_result", result_index)
-def test_add(a, b, expected_result):
+def test_add(a: int, b: int, expected_result: int) -> None:
assert add_function.add(a, b) == expected_result
diff --git a/testing/test_mark.py b/testing/test_mark.py
index 2896afa45..eefedf15e 100644
--- a/testing/test_mark.py
+++ b/testing/test_mark.py
@@ -419,10 +419,13 @@ def test_parametrized_collect_with_wrong_args(pytester: Pytester) -> None:
result = pytester.runpytest(py_file)
result.stdout.fnmatch_lines(
[
- 'test_parametrized_collect_with_wrong_args.py::test_func: in "parametrize" the number of names (2):',
- " ['foo', 'bar']",
- "must be equal to the number of values (3):",
- " (1, 2, 3)",
+ "test_parametrized_collect_with_wrong_args.py::test_func: ",
+ "",
+ ' Error in parameterization for test "test_func".',
+ " The number of specified parameters (2) does not match the number of provided values (3): 1, 2, 3. ",
+ " Please ensure that the correct number of parameter names (3) are separated by commas within quotes.",
+ "",
+ 'Require more than parameter names: "foo, bar"',
]
)