diff --git a/docs/advanced.rst b/docs/advanced.rst index 41d9d1e168..1fd8ad38cf 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -302,12 +302,11 @@ Depending on that value, the test is set up differently: If you have already gone through the `tutorial `__, this test can be easily understood. The new bit here is the ``@parameterized_test`` decorator of the ``MatrixVectorTest`` class. -This decorator takes as argument an iterable of either sequence (i.e., lists, tuples etc.) or mapping types (i.e., dictionaries). -Each of this iterable's elements corresponds to the arguments that will be used to instantiate the decorated test each time. -In the example shown, the test will instantiated twice, once passing ``variant`` as ``MPI`` and a second time with ``variant`` passed as ``OpenMP``. +This decorator takes an arbitrary number of arguments, which are either of a sequence type (i.e., list, tuple etc.) or of a mapping type (i.e., dictionary). +Each of the decorator's arguments corresponds to the constructor arguments of the decorated test that will be used to instantiate it. +In the example shown, the test will be instantiated twice, once passing ``variant`` as ``MPI`` and a second time with ``variant`` passed as ``OpenMP``. The framework will try to generate unique names for the generated tests by stringifying the arguments passed to the test's constructor: - .. code-block:: none Command line: ./bin/reframe -C tutorial/config/settings.py -c tutorial/advanced/advanced_example8.py -l @@ -336,14 +335,14 @@ The dictionaries will be converted to keyword arguments and passed to the constr .. code-block:: python - @rfm.parameterized_test([{'variant': 'MPI'}, {'variant': 'OpenMP'}]) + @rfm.parameterized_test({'variant': 'MPI'}, {'variant': 'OpenMP'}) Another way, which is quite useful if you want to generate lots of different tests at the same time, is to use either `list comprehensions `__ or `generator expressions `__ for specifying the different test instantiations: .. code-block:: python - @rfm.parameterized_test((variant,) for variant in ['MPI', 'OpenMP']) + @rfm.parameterized_test(*([variant] for variant in ['MPI', 'OpenMP'])) .. note:: diff --git a/reframe/core/decorators.py b/reframe/core/decorators.py index ba39cf89e6..ae8e9f3001 100644 --- a/reframe/core/decorators.py +++ b/reframe/core/decorators.py @@ -57,16 +57,15 @@ def simple_test(cls): return cls -def parameterized_test(inst=[]): +def parameterized_test(*inst): """Class decorator for registering multiple instantiations of a test class. The decorated class must derive from - :class:`reframe.core.pipeline.RegressionTest`. This decorator is also + :class:`reframe.core.pipeline.RegressionTest`. This decorator is also available directly under the :mod:`reframe` module. - :arg inst: An iterable of the argument lists of the difference - instantiations. Instantiation arguments may also be passed as - keyword dictionaries. + :arg inst: The different instantiations of the test. Each instantiation + argument may be either a sequence or a mapping. .. versionadded:: 2.13 @@ -74,6 +73,7 @@ def parameterized_test(inst=[]): This decorator does not instantiate any test. It only registers them. The actual instantiation happens during the loading phase of the test. + """ def _do_register(cls): _validate_test(cls) diff --git a/tutorial/advanced/advanced_example8.py b/tutorial/advanced/advanced_example8.py index 6f4d8417f0..487843c8dc 100644 --- a/tutorial/advanced/advanced_example8.py +++ b/tutorial/advanced/advanced_example8.py @@ -2,7 +2,7 @@ import reframe.utility.sanity as sn -@rfm.parameterized_test([('MPI',), ('OpenMP',)]) +@rfm.parameterized_test(['MPI'], ['OpenMP']) class MatrixVectorTest(rfm.RegressionTest): def __init__(self, variant): super().__init__() diff --git a/unittests/resources/checks_unlisted/good.py b/unittests/resources/checks_unlisted/good.py index 211aee9507..fdd7947459 100644 --- a/unittests/resources/checks_unlisted/good.py +++ b/unittests/resources/checks_unlisted/good.py @@ -8,7 +8,7 @@ from reframe.core.pipeline import RegressionTest -@rfm.parameterized_test((x, y) for x in range(3) for y in range(2)) +@rfm.parameterized_test(*((x, y) for x in range(3) for y in range(2))) class MyBaseTest(RegressionTest): def __init__(self, a, b): super().__init__() @@ -26,7 +26,7 @@ def __repr__(self): return 'MyBaseTest(%s, %s)' % (self.a, self.b) -@rfm.parameterized_test({'a': x, 'b': y} for x in range(3) for y in range(2)) +@rfm.parameterized_test(*({'a': x, 'b': y} for x in range(3) for y in range(2))) class AnotherBaseTest(RegressionTest): def __init__(self, a, b): super().__init__() diff --git a/unittests/resources/checks_unlisted/mixed.py b/unittests/resources/checks_unlisted/mixed.py index 298a377016..e33a778966 100644 --- a/unittests/resources/checks_unlisted/mixed.py +++ b/unittests/resources/checks_unlisted/mixed.py @@ -4,7 +4,7 @@ from reframe.core.pipeline import RegressionTest -@deco.parameterized_test((x, y) for x in range(3) for y in range(2)) +@deco.parameterized_test(*((x, y) for x in range(3) for y in range(2))) class MyBaseTest(RegressionTest): def __init__(self, a, b): super().__init__()