Even if there are multiple means of transportation to reach the destination in the real world, such as walking, car, and public transportation, the destination is one of the destinations, but how much each means can be affected by the price, time, and accident. There are advantages and disadvantages such as.
Similarly, when writing code, there can be multiple ways to achieve the same goal.
For example, when searching a tree, there are multiple search methods such as depth-first and breadth-first, which have advantages and disadvantages. The sorting algorithm is similar. It's a bit overstated, but similar cases can occur in cases like Strategy in the design pattern.
In the case of selecting depth-first in some cases and breadth-first in some cases, each test case will be placed in the code, and if you want to perform a black box test without being aware of the contents of the code, implement it honestly. Then there will be duplicate similar test code.
In such a case, I will write a story that load_tests () can be used to write code that limits test cases.
As an example, consider implementing the multiplication of integers x and y in two ways, "adding y x times" and "multiplication", and implementing each test.
A naive implementation would result in the following code. Comment The part written as "redundant" is redundant.
import unittest
class MultiplyBase(object):
def multiply(self, n1: int, n2: int) -> int:
raise NotImplementedError()
class MultiplyPlus(MultiplyBase):
def multiply(self, n1: int, n2: int) -> int:
ret = 0
for i in range(0, n1):
ret += n2
return ret
class MultiplyAsterisk(MultiplyBase):
def multiply(self, n1: int, n2: int) -> int:
return n1 * n2
class TestMultiplyBase(unittest.TestCase):
def test_multiply(self):
obj: MultiplyBase = MultiplyBase()
with self.assertRaises(NotImplementedError):
obj.multiply(2, 3)
class TestMultiplyPlus(unittest.TestCase):
def test_multiply(self):
obj: MultiplyBase = MultiplyPlus()
self.assertEqual(obj.multiply(2, 3), 6) #Redundancy!!
class TestMultiplyAsteriskClass(unittest.TestCase):
def test_multiply(self):
obj: MultiplyBase = MultiplyAsterisk()
self.assertEqual(obj.multiply(2, 3), 6) #Redundancy!!
I don't really care about this amount, but it's hard when it's large.
We will implement a test case in the TestCaseHelper class and derive this test case to create a concrete test case.
With TestCaseHelper, each test case class only needs to implement which class of objects it uses. This eliminates redundant code.
However, in this case, the TestCaseHelper class will be discovered with the default behavior of unittest. Because of this, test cases always fail, so load_tests () prevents TestCaseHelper from being considered a test case.
import unittest
class MultiplyBase(object):
def multiply(self, n1: int, n2: int) -> int:
raise NotImplementedError()
class MultiplyPlus(MultiplyBase):
def multiply(self, n1: int, n2: int) -> int:
ret = 0
for i in range(0, n1):
ret += n2
return ret
class MultiplyAsterisk(MultiplyBase):
def multiply(self, n1: int, n2: int) -> int:
return n1 * n2
class TestCaseHelper(unittest.TestCase):
def _get_multiply_obj(self) -> MultiplyBase:
raise NotImplementedError()
def test_multiply(self):
obj: MultiplyBase = self._get_multiply_obj()
self.assertEqual(obj.multiply(2, 3), 6)
class TestMultiplyBase(TestCaseHelper):
def _get_multiply_obj(self) -> MultiplyBase:
return MultiplyBase()
def test_multiply(self):
obj: MultiplyBase = self._get_multiply_obj()
with self.assertRaises(NotImplementedError):
obj.multiply(2, 3)
class TestMultiplyPlus(TestCaseHelper):
def _get_multiply_obj(self) -> MultiplyBase:
return MultiplyPlus()
class TestMultiplyAsterisk(TestCaseHelper):
def _get_multiply_obj(self) -> MultiplyBase:
return MultiplyAsterisk()
def load_tests(loader, tests, patterns):
test_cases = (TestMultiplyBase, TestMultiplyPlus, TestMultiplyAsterisk)
suite = unittest.TestSuite()
for test_class in test_cases:
tests = loader.loadTestsFromTestCase(test_class)
suite.addTests(tests)
return suite
You have now successfully excluded some test cases with load_tests ().
Recommended Posts