unittest: Add addCleanup to subTest? (original) (raw)

I think we shoud just do exactly what pytest does. There is a good reason why people use pytest and there is a good reason why pytest.parametrize works the way it works. So I think it should really work similarly, or at least, have similar semantics.

IIRC, pytest.parametrize() creates new functions; this also means that every setUp/tearDown logic is duplicated, so we should be aware of side-effects.

So, we should create new methods. OTOH, we could also make the choice of having a subtest() method which simply creates subtests instead of new tests.

what exactly happens when you apply more of them

It becomes a product, namely

@parametrize('a', [1,2,3])
@parametrize('b', [4,5,6])
def test_foo(self, a, b)

should be equivalent to call test_foo with all possible (a, b) pairs.

Can you parametrize dynamically, with a generator?

Well, you could dynamically parametrize but this means that the generator must be consumed when executing the class body:

class A:
    @parametrize('a', iter('1234'))
    def test_a(self, a): ...

should be valid. I don’t really see what you meant by “dynamically” otherwise. Are you suggesting that a test function can be executed and more cases would be dynamically added to it? where would you call this parametrization method? something like:

def test_foo(self):
    for param in self.parametrize_more(iter([1,2,3,4])):
        do_some_test_with_param(...)

I had a similar idea where doing:

def test_foo(self):
    for a, b in self.parametrize_more("what", a=[1,2,3], b=[4,5,6]):
        do_some_test_with_param(a, b)

would be equivalent to:

def test_foo(self):
    for a, b in product([1,2,3], [4,5,6]):
        with self.subTest("what", a=a, b=b):
            do_some_test_with_param(a, b)

The product-approach usually saves a lot of indentation at the cost of some readbility.