Using setUp defined variables in parametrized.expand
Asked Answered
B

3

7

Suppose that I have the following unit test class:

class Test(unittest.TestCase)
    def setUp(self) -> None:
        self.test_parameter1 = 'A'
        self.test_parameter2 = 'B'
    
    @parametrized.expand([('A',), ('B',)])
    def test_function1(self, test_param):
        * Do tests here *

Is there a way how can I use self.test_parameter1 and self.test_parameter2 in parameterized.expand instead of the literals A and B? Imagine A and B are large dicts, the tests would be very messy in this case if two large dicts are given to parametrized_expand.

Bruges answered 12/2, 2021 at 17:18 Comment(1)
Welcome to stackoverlow ! Afaik this is not possible => tests are expanded before testclasses are initiated... maybe if your self_test_paramter1 is a callable ... but thats something to be tried I'll follow your questionMalvie
O
1

Note that I've used the spelling "parameterized" rather than "parametrized" throughout my answer.

You could pass them as strings to @parameterized.expand and then eval them in the function:

class Test(unittest.TestCase)
def setUp(self) -> None:
    self.test_parameter1 = 'A'
    self.test_parameter2 = 'B'

@parameterized.expand([('self.test_parameter1',), ('self.test_parameter2',)])
def test_function1(self, test_param):
    test_param = eval(test_param)
    # * Do tests here *

Presumably you're in control of the entire test file, so eval shouldn't raise the security concerns that it would if it were called on unknown code.

Oliguria answered 19/6 at 22:54 Comment(0)
V
0

Yes - test_function is a method on your Test class so in your test_function you just need to use self.test_parameter1 & self.test_parameter2 where you would use A & B.

For example:

    @parametrized_expand([('A',), ('B',)])
    def test_function1(self, test_param):
       self.assertEqual(test.parameter1 + self.test_paramter2, 10)
Vesicate answered 12/2, 2021 at 17:24 Comment(2)
What I meant is using self.test_parameter1 and self.test_parameter2 instead of 'A' and 'B' inside the parameterized.expand decoratorBruges
@DylanGalea - no - because of when the decorator is executed, those attributes don't exist. The best you could do is pass the names of the parameters, and then use getattr to fetch the attributes. But if you are storing them as attributes, then why do you need them as paramterised too ?Vesicate
P
0

Perhaps you can set them up to be references outside of the test class (they'll be executed on import by unittest) and expand (*) or unzip 'em in the decorator args

test_parameter1 = dict_A
test_parameter2 = dict_B

expanded_args = list(zip(test_parameter1.items(), test_parameter2.items()))

class Test(unittest.TestCase)
    @parametrized.expand(expanded_args)
    def test_function1(self, test_param):
        * Do tests here *
Pitchdark answered 12/2, 2021 at 17:44 Comment(4)
This could be a good option. But I was looking for a way such that the parameters are then re-declared by setUp, just in case no other test messes up with the variables declared outside the class.Bruges
Perhaps you could call .copy() on 'em before passing to .expand()?Pitchdark
Another option I found was to pass the variable name is parametrized.expand and then use eval.Bruges
@DylanGalea could you please give an example how you used eval within your expand? I struggle with the same problem.Suture

© 2022 - 2024 — McMap. All rights reserved.