Search code examples
pythonunit-testingtdd

python unittest methods which call other methods


implementing basic space geometry class

Class Geometry(object):

    # radius is required and must be float
    def circleSurface(self, radius):
        if not isinstance(radius, float):
            raise AttributeError("best to enter a float as radius")
        else:
            return radius*radius*3.14

    # height and radius are required and must be floats
    def cylinderVolume(self, radius, height):
        if not isinstance(height, float):
            raise AttributeError("best to enter a float as height")
        else:
            return self.circleSurface(radius) * height

      

and writing a basic geometry class tester

import unittest
import Geometry

class GeometryTest(unittest.TestCase):
    def test_circleSurfaceRaisesAttributeErrorWhenRadiusIsNotFloat(self):
        with self.assertRaises(AttributeError) as raised_exception:
            Geometry.circleSurface(radius = "B")
        self.assertEqual(str(raised_exception.exception), "best to enter a float as radius")

    def test_cylinderVolumeRaisesAttributeErrorWhenHeightIsNotFloat(self):
        with self.assertRaises(AttributeError) as raised_exception:
            Geometry.cylinderVolume(radius = 1.0, height = "B")
        self.assertEqual(str(raised_exception.exception), "best to enter a float as height")

Seems to do it, but I also like to test, in the cylinderVolume method, if or not the radius is a float, even though it comes intrinsic with the call to circleSurface Method:

    def test_cylinderVolumeRaisesAttributeErrorWhenRadiusIsNotFloat(self):
        with self.assertRaises(AttributeError) as raised_exception:
            Geometry.cylinderVolume(radius = "B", height = 1.0)
        self.assertEqual(str(raised_exception.exception), "best to enter a float as radius")

It feels so natural to test all arguments of the call to cylinderVolume.

I know adding the last test is not going to cause any 'overhead' or significant time consumption and you might as well just do it, but on the other hand it seems a bit redundant, overkill and duplication of code. Just wondered if there was a certain standard of addressing this kind of tests.


Solution

  • That cylinderVolume calls circleSurface is an implementation detail. You know that the validation of radius happens for cylinderVolume now but after a refactoring this could change. If you want to ensure against this regression you should test the validation of radius for cylinderVolume.