3

I want to name the test dynamically during run-time when i run them with the @pytest.mark.parametrize("value",values_list) fixture. for example:

values_list=['apple','tomatoes','potatoes']

@pytest.mark.parametrize("value",values_list)
def test_xxx(self,value):
    assert value==value

the final outcome i want to see is 3 tests with the following names:

test_apple

test_tomatoes

test_potatoes

i gave tried looking in to pytest documentation but i haven found anything that might shed light on this problem.

hoefling
  • 59,418
  • 12
  • 147
  • 194
Bored002
  • 353
  • 6
  • 18
  • 4
    You cannot do this. All you can is to set custom name for every option in `parametrize` values by setting `ids` arguments. Take a look at https://docs.pytest.org/en/latest/example/parametrize.html#different-options-for-test-ids (test `test_timedistance_v1`). You can customize the value displayed in square brackets during test run. – wiaterb Apr 20 '20 at 08:36

1 Answers1

7

You can change the names displayed in test execution by rewriting the _nodeid attibute of the test item. Example: create a file named conftest.py in your project/test root dir with the following contents:

def pytest_collection_modifyitems(items):
    for item in items:
        # check that we are altering a test named `test_xxx`
        # and it accepts the `value` arg
        if item.originalname == 'test_xxx' and 'value' in item.fixturenames:
            item._nodeid = item.nodeid.replace(']', '').replace('xxx[', '')

Running your tests will now yield

test_fruits.py::test_apple PASSED
test_fruits.py::test_tomatoes PASSED
test_fruits.py::test_potatoes PASSED

Beware that overwriting _nodeid should be enjoyed with caution as each nodeid should remain unique. Otherwise, pytest will silently drop executing some tests and it will be hard to find out why.

hoefling
  • 59,418
  • 12
  • 147
  • 194
  • Thanks will try that and will let you know – Bored002 Apr 22 '20 at 04:16
  • Great it worked , but now i want to add another layer of complexity. Let's say that : ``` values_list=[{'apple':'5'},{'tomatoes':'1'},{'potatoes': '32}] ``` I want the name of the test to be test_5, test_1 and so on , is there a way to access those values ? I've tried doing that via the setup_method in the test class itself, but i cant access the dictionary from there (even in debug). – Bored002 Apr 22 '20 at 06:40
  • 2
    Thanks in advance but i managed to figure it out , it took some digging but eventually i've discovered it was sitting in a nsested structure inside : iitem.own_markers[0].args[1] So i did some maniuplation with that data and managed to extract the required field – Bored002 Apr 22 '20 at 08:08