gpt4 book ai didi

Python:测试类的单个方法的最佳方法

转载 作者:太空狗 更新时间:2023-10-29 20:54:34 24 4
gpt4 key购买 nike

我有一个类如下:

class A:
def __init__(self, arg1, arg2, arg3):
self.a=arg1
self.b=arg2
self.c=arg3
# ...
self.x=do_something(arg1, arg2, arg3)
self.y=do_something(arg1, arg2, arg3)

self.m = self.func1(self.x)
self.n = self.func2(self.y)
# ...

def func1(self, arg):
# do something here

def func2(self, arg):
# do something here

如您所见,初始化类需要输入 arg1、arg2 和 arg3。然而,测试 func1 和 func2 并不直接需要这样的输入,而是简单的输入/输出逻辑。

在我的测试中,我当然可以通过常规的方式实例化和初始化一个测试对象,然后分别测试func1和func2。但是初始化需要输入arg1 arg2,arg3,这与测试func1和func2确实无关。

因此,我想单独测试 func1 和 func2,而不先调用 __init__。所以我有以下两个问题:

  1. 设计此类测试的最佳方法是什么? (最好在 py.test 中)
  2. 我想测试 func1 和 func2 而不调用 __init__。我读自 here A.__new__() 可以跳过调用 __init__ 但仍然实例化类。有没有更好的方法可以在不这样做的情况下实现我的需求?

注意:

关于我在这里的提问有 2 个问题:

  1. 是否需要测试单个成员函数?
  2. (用于测试目的)是否有必要在不使用__init__ 初始化对象的情况下实例化类?

对于问题 1,我进行了快速的 google 搜索并找到了一些相关的研究或讨论:

We initially test base classes having no parents by designing a test suite that tests each member function individually and also tests the interactions among member functions.

对于问题 2,我不确定。但是我觉得有必要,如示例代码所示,在__init__中调用了func1和func2。我觉得在尚未使用 __init__ 调用(因此之前没有调用 func1 和 func2)的类 A 对象上测试它们会更舒服。

当然,也可以用常规方法(testobj = A())实例化一个A类对象,然后分别对func1和func2进行测试。但它好吗:)?我只是在这里讨论测试这种情况的最佳方法是什么,利弊是什么。

另一方面,有人可能会争辩说,从设计的角度来看,一开始就不应该在 __init__ 中调用 func1 和 func2。这是一个合理的设计选项吗?

最佳答案

在不实例化类(包括运行 __init__)的情况下测试类的方法通常没有用,甚至不可能。通常,您的类方法将引用类的属性(例如,self.a)。如果您不运行 __init__,这些属性将不存在,因此您的方法将不起作用。 (如果您的方法不依赖于它们实例的属性,那么为什么它们是方法而不仅仅是独立函数?)在您的示例中,它看起来像 func1func2 是初始化过程的一部分,因此应将它们作为初始化过程的一部分进行测试。

理论上,可以通过使用 __new__ 然后仅添加您需要的成员来“准实例化”该类,例如:

obj = A.__new__(args)
obj.a = "test value"
obj.func1()

但是,这可能不是进行测试的好方法。一方面,它会导致您复制可能已经存在于初始化代码中的代码,这意味着您的测试更有可能与真实代码不同步。另一方面,您可能必须以这种方式重复许多初始化调用,因为您必须手动重新执行从您的类调用的任何基类 __init__ 方法否则会执行的操作。

至于如何设计测试,可以看看the unittest module和/或 the nose module .这为您提供了如何设置测试的基础知识。实际放入测试中的内容显然取决于您的代码应该做什么。

编辑:问题 1 的答案是“肯定是,但不一定是每个人”。问题 2 的答案是“可能不会”。即使在您提供的第一个链接中,也存在关于是否应该测试不属于该类公共(public) API 的方法的争论。如果你的 func1 和 func2 是纯粹的内部方法,只是初始化的一部分,那么可能没有必要在初始化之外单独测试它们。

这就是你的最后一个问题,即从 __init__ 中调用 func1 和 func2 是否合适。正如我在评论中反复声明的那样,这取决于这些函数的作用。如果 func1 和 func2 执行部分初始化(即为实例做一些“设置”工作),那么从 __init__ 调用它们是完全合理的;但在那种情况下,它们应该作为初始化过程的一部分进行测试,没有必要单独测试它们。如果 func1 和 func2 不是初始化的一部分,那么是的,您应该独立测试它们;但在那种情况下,为什么它们在 __init__ 中?

构成类实例化不可分割部分的方法应作为类实例化测试的一部分进行测试。不应从 __init__ 中调用不构成实例化类不可分割部分的方法。

如果 func1 和 func2 是“简单的输入/输出逻辑”并且不需要访问实例,那么它们根本不需要是类的方法;它们可以只是独立的功能。如果你想将它们保留在类中,你可以将它们标记为静态方法,然后直接在类上调用它们而不实例化它。这是一个例子:

>>> class Foo(object):
... def __init__(self, num):
... self.numSquared = self.square(num)
...
... @staticmethod
... def square(num):
... return num**2
>>> Foo.square(2) # you can test the square "method" this way without instantiating Foo
4
>>> Foo(8).numSquared
64

可以想象,您可能有一些需要极其复杂的初始化过程的怪物类。在这种情况下,您可能会发现有必要单独测试该流程的各个部分。然而,这样一个巨大的初始化序列本身就是一个笨拙设计的警告。

关于Python:测试类的单个方法的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11623800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com