unittest - making setUp() the single source of truth for test data and its effect on parallelized testing

135 views Asked by At

As far as I know, using unittest in Python is done something like this -

# test.py
import unittest
import math
from my_math import do_math

class test_do(unittest.TestCase):

    def test_first_case(self):
        self.assertEqual(math.sqrt(4), do_math.sqroot(4))
        self.assertEqual(math.sqrt(9), do_math.sqroot(9))

if __name__ == "__main__":
    unittest.main()

My concern is specifically with the computation we need to perform to verify the test results. If we use the setUp() method, we could restructure the code as follows

# test.py
import unittest
import math
from my_math import do_math

class test_do(unittest.TestCase):

    def setUp(self):
        self.test_1 = 4
        self.test_2 = 9
        self.test_sqroot_1 = math.sqrt(self.test_1)
        self.test_sqroot_2 = math.sqrt(self.test_2)

    def test_first_case(self):
        self.assertEqual(self.test_sqroot_1, do_math.sqroot(self.test_1))
        self.assertEqual(self.test_sqroot_2, do_math.sqroot(self.test_2))

if __name__ == "__main__":
    unittest.main()

If I need to refactor the testcases in terms of true or target values, I will need to change just the setUp() function body, whereas I would need to make changes everywhere in the first approach (considering multiple testcases accessing the same data).

My question is this - in terms of parallelized testing, given that I am doing most of the computation needed for verification in the setUp() function and not in the testcase functions themselves, is the second approach adviseable?

1

There are 1 answers

1
EricSchaefer On

Why do you need to calculate the square root of 4 and 9 multiple times? Why not precalculate it, especially in such trivial cases?

self.test_1 = 4
self.test_2 = 9
self.test_sqroot_1 = 2
self.test_sqroot_2 = 3

Edit (based on comment):

Even if the calculation is more involved, I would never do it like this. The setup of a test should be as simple and quick as possible. If the calculation would yield the same result for each test, why do it at all. Calculate once and set as constant value.

On the other hand, if the calculation has side-effects that are needed for the tests, e.g. it is actually setting up a database or similar, then call it a setup, not a calculation. In this case it does, in fact, belong in the setup method. Such complicated and time consuming setups should still be generally avoided, except for integration or end-to-end tests which are expected to be slow and should be kept to a minimum.