[TIP] py.test: How to define a test function with two or more parametrized arguments?

Stefano Lattarini stefano.lattarini at gmail.com
Sat Mar 20 12:35:59 PDT 2010


Hello everybody.

I want to make it clear first that I'm a newbie when it comes to py.test,
and I still don't understand test parametrization and funcargs very well,
so please forgive me if this is a stupid or badly formulated question.

Also, you might found it useful to know that I'm using python 2.5 and
python 3.1 on Debian GNU/Linux, and that my py.test's version is 1.2.1.

My question is: there is a way to define a test function with two or more
parametrized arguments (provided by a `pytest_generate_tests' hook), in a
way that forces the test function to run with *all possible combinations*
of those parametrized tests?

An example might help to clarify the matter.

I tried this:

  def pytest_generate_tests(metafunc):
      if "an_even_number" in metafunc.funcargnames:
          for e in (0, 2, 4, 6):
              metafunc.addcall(funcargs={'an_even_number': e})
      if "an_odd_number" in metafunc.funcargnames:
          for o in (1, 3, 5, 7):
              metafunc.addcall(funcargs={'an_odd_number': o})

  def test_with_multiple_parametrized_args(an_even_number, an_odd_number):
      assert (an_even_number + an_odd_number) % 2 == 1

expecting 16 tests to be run, one for each couple (x, y) with  x = 0, 2, 4, 6
and  y = 1, 3, 5, 7.

Instead, I got the following error:
  
  $ py.test-2.5 test_foo.py
  ==== test session starts ====
  python: platform linux2 -- Python 2.5.4 -- pytest-1.2.1                                                                      
  test object 1: test_foo.py                                                                                                   

  test_foo.py EEEEEEEE

  ===== ERRORS =====
  ______ ERROR at setup of test_with_multiple_parametrized_args[0] ________

    def test_with_multiple_parametrized_args(an_even_number, an_odd_number):
        LookupError: no factory found for function argument 'an_odd_number' 
        available funcargs: pytestconfig, capsys, capfd, tmpdir, monkeypatch, recwarn
        use 'py.test --funcargs [testpath]' for help on them.                        
  
  /home/stefano/test_foo.py:9
  
  ... [ SIMILAR ERRORS CUT]

  _____ ERROR at setup of test_with_multiple_parametrized_args[7] _________

    def test_with_multiple_parametrized_args(an_even_number, an_odd_number):
        LookupError: no factory found for function argument 'an_even_number'
        available funcargs: pytestconfig, capsys, capfd, tmpdir, monkeypatch, recwarn
        use 'py.test --funcargs [testpath]' for help on them.

  /home/stefano/test_foo.py:9
  ============== 8 error in 0.19 seconds ==============

I experienced the same error also using python3.1.

So, I'm doing something wrong here?  There is an indiom/option I am not aware
of?  Is it even possible to do what I'm trying to accomplish?  

Any help will be appreciated.

Regards,
     Stefano

P.S. Of course, I could use nose-style test generators as a workaround, but I'd
prefer to stick with `pytest_generate_tests' and parametrized tests if possible.



More information about the testing-in-python mailing list