Python 3.9 - class 中的联合测试方法

Python 3.9 - Unitesting method in class

初学者级别的问题,我是新手,想学习在我的代码中使用单元测试。我看过一些如何制作单元测试的教程,但是当要在自己的代码上练习时,我开始想知道如何正确地制作它以避免学习不良的代码习惯。

我有一个 class 几何将被其他 class 继承,class 使用导入的自定义对象(namedtuple“Point”)和列表 json带有配置的文件,但这将由代码的其他部分提供。这是我的问题:

  1. 我的单元测试应该只检查 class 方法 create_geometry 和 calculate_drag_surfaces 还是上面提到的所有方法以及使用 init 方法创建实例?
  2. 当我创建影响实例 属性 的方法的统一测试时,就像 create_geometry 方法一样,断言应该是什么样子?我应该检查更改实例的值 属性 或者有一种方法可以在不创建新实例的情况下“就地”测试它?
  3. 我应该如何为受保护或隐藏的方法进行单元测试,我的意思是它们有什么区别吗?

如果您在我的代码中发现任何问题,我愿意听取任何建议,我没有任何商业经验,想尽可能多地学习。下面我展示了我想用 unittest 测试的代码。

from point import Point


class Geometry:
    """
    Geometry class - object that will keep geometry dependent information necessary for
    graphic render and physic calculations
    """
    def __init__(self, geometry_points_cords, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry_points = []  # list of named tuples with co-ords on flat surface
        self.__create_geometry(geometry_points_cords)
        self.x_drag_surface = None
        self.y_drag_surface = None
        self.__calculate_drag_surfaces()

    def __create_geometry(self, geometry_points_cords):
        """
        Method that will convert provided geometry points into namedtuples that describe
        geometry on x/y plane
        :param geometry_points_cords:
        :return:
        """
        for geometry_cords in geometry_points_cords:
            self.geometry_points.append(Point(geometry_cords[0], geometry_cords[1]))

    def __calculate_drag_surfaces(self):
        """
        Method that will calculate drag surfaces in each axis base on geometry
        :return:
        """
        x_cords = []
        y_cords = []
        for single_point in self.geometry_points:
            x_cords.append(single_point.x)
            y_cords.append(single_point.y)
        self.x_drag_surface = (max(x_cords) - min(x_cords))**2
        self.y_drag_surface = (max(y_cords) - min(y_cords))**2

接口是x_drag_surfacey_drag_surface这两个字段吗?然后你应该主要测试那些得到正确的值。

geometry = Geometry(some_coordinates)
assert geometry.x_drag_surface = correct_x_drag_surface
assert geometry.y_drag_surface = correct_y_drag_surface

由于代码是现在编写的,因此您无法分别测试 __create_geometry__calculate_drag_surfaces,因为构造函数会将它们都设为 运行。不过,您可以从 class 中提取它们,并使它们可测试:

def make_points(coordinates):
    """
    Method that will convert provided geometry points into namedtuples that describr geometry on x/y plane
    :param geometry_points_cords:
    :return:
    """
    return [ Point(x, y) for (x, y) in coordinates]


def calculate_drag_surfaces(points):
    """
    Method that will calculate drag surfaces in each axis base on geometry
    :return:
    """
    x_coords = list(map(lambda p: p.x, points))
    y_coords = list(map(lambda p: p.y, points))
    
    x_drag_surface = (max(x_coords) - min(x_coords))**2
    y_drag_surface = (max(y_coords) - min(y_coords))**2

    return x_drag_surface, y_drag_surface


class Geometry:
    """
    Geometry class - object that will keep geometry dependent information necessary for
    graphic render and physic calculations
    """
    def __init__(self, coordinates, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry_points = make_points(coordinates)  # list of named tuples with co-ords on flat surface
        self.x_drag_surface, self.y_drag_surface = calculate_drag_surfaces(self.geometry_points)