pythonrowspytestparameterized-tests

pytest parameterize - row from CSV as a testcase


I have to read a CSV file and for each combination in each row need to run some methods.I would like to see each row as a test case. Is it possible to send row as a param - pytest parameterize my test case? Can you please give me some idea on how to do that?

Here is the pseudo code:

class test_mytest:
  def test_rows:
    for row in csvreader:
       run_method(row)
       for onecol in row:
          run_method2(onecol)

I have tried reading the pytest documentation but it was not clear for me.

Here is what I am doing for using generate_tests hook for row as a param.I would like to know how to do same for the inner for loop function-this inner loop also should be collected as a test case

def pytest_generate_tests(metafunc):
    read_csvrows()
    for funcargs in metafunc.cls.params[metafunc.function.__name__]:
        # schedule a new test function run with applied **funcargs
        metafunc.addcall(funcargs=funcargs)

class TestClass:

    params = {
       'test_rows': rows,   
    }
    def test_rows:
        run_method(row)
        for onecol in row:
             test_method2(onecol)

Now, I need to generate reports for the -for loop calling test_method2 (it is parameterized method for list of elements in the column in each row of csv file). Pytest needs to collect those as test case as well.

Appreciate your help.Thanks


Solution

  • You will probably want to use the pytest_generate_tests() hook as described here: https://docs.pytest.org/en/stable/parametrize.html#pytest-generate-tests This allows you to read the csv file and parametrize the tests you want based on it's contents.

    Update:

    The updated question seems not entirely clear, but I'm assuming you need to test something on a row as well as on a column. This simply asks for two tests:

    def test_row(row):
        assert row  # or whatever
    
    def test_column(col):
        assert col  # or whatever
    

    Now all that remains is to create the parametrized fixtures for row and col using the pytest_generate_tests() hook. So in the conftest.py file:

    def test_generate_tests(metafunc):
        rows = read_csvrows()
        if 'row' in metafunc.fixturenames:
            metafunc.parametrize('row', rows)
        if 'col' in metafunc.fixturenames:
            metafunc.parametrize('col', list(itertools.chain(*rows)))
    

    Notice the use of the recommended metafunc.parametrize() function instead of the deprecated metafunc.addcall()