simplest way of parameterizing tests in python?

2019-06-14 17:49发布

问题:

I have a library with a bunch of different objects that have similar expected behavior, thus I want to run similar tests on them, but not necessarily identical tests on them.

To be specific lets say I have some sorting functions, and a test for checking if a sorting function actually sorts. Some sorting functions are intended to work on some inputs, but not others.

I'd like to write something close to the code below. However, nose won't do a good job of telling me exactly where the tests failed and with what inputs. If check_sort fails for sort2 on case2, I won't be able to see that.

def check_sort(sortalg, vals):
     assert sortalg(vals) == sort(vals)


def test_sorts(): 
    case1 = [1,3,2]
    case2 = [2,31,1]

    check_sort(sort1, case1)

    for c in [case1, case2]: 
        check_sort(sort2, c)

I would like to be able to simply add a decorator to check_sort to tell nose that it's a nested test. Something like

@nested_test
def check_sort(sortalg, vals):
     assert sortalg(vals) == sort(vals)

The idea being that when it gets called, it registers itself with nose and will report its inputs if it fails.

It looks like pytest provides pytest.mark.parameterized, but that seems rather awkward to me. I have to put all my arguments above the function in one spot, so I can't call it repeatedly in my tests. I also don't think this supports nesting more than one level.

Nose also provides test generators, which seems closer, but still not as clear as I would hope.

回答1:

Using the provided generative test feature is the likely intended way to do it with nose and py.test.

That said, you can dynamically add functions (tests) to a class after it has been created. That is the technique used by the Lib/test/test_decimal.py code in the standard library.



回答2:

You can use nose-ittr, its a nose extension for supporting parametrized testing.

example:

@ittr(case1=[1,3,2],case2=[2,31,1])
def test_sorts(): 

check_sort(sort1, self.case1)
check_sort(sort2, self.case2)