【问题标题】:__init__ takes one argument 2 given unittest__init__ 接受一个参数 2 给定的 unittest
【发布时间】:2017-02-17 03:15:40
【问题描述】:

我收到以下错误

TypeError: __init__() takes exactly 1 argument (2 given)

当我运行以下 python 时:

import unittest
from unittest import TestCase

class myClass( unittest.TestCase ):

    def __init__( self ):
        pass

if __name__ == '__main__':
    unittest.main( argv=sys.argv, testRunner = unittest.TextTestRunner(verbosity=2))

有什么想法吗?我需要运行 init,因为我只想做一次设置工作。不是每次测试一次。这将是对整体测试运行时间的重大优化。

这是堆栈爬取的其余部分:

Traceback (most recent call last):
File "./RestEditRecord.py", line 1439, in <module>
unittest.main( argv=sys.argv, testRunner = unittest.TextTestRunner(verbosity=2))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 94, in __init__
self.parseArgs(argv)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 149, in parseArgs
self.createTests()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 155, in createTests
self.test = self.testLoader.loadTestsFromModule(self.module)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/loader.py", line 65, in loadTestsFromModule
tests.append(self.loadTestsFromTestCase(obj))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/loader.py", line 56, in loadTestsFromTestCase
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
TypeError: __init__() takes exactly 1 argument (2 given)

【问题讨论】:

  • 你需要调用超级构造函数吗?
  • 使用setUpClass() 而不是__init__()

标签: python python-unittest


【解决方案1】:

阅读the docs for the class you're extending; unittest.TestCase 的初始化器接受一个可选参数,如果你不接受它,并且它被传递,你会得到这个错误。

无论如何,很少有充分的理由为TestCase 覆盖__init__;测试设置在setUp 中完成(每个测试运行一次,因此从一个测试更改状态不会影响另一个测试的行为),而不是__init__(总共运行一次)。您将继承 __init__,并且由于您的 __init__ 没有做任何额外的事情,所以拥有它是愚蠢的。

如果您确实对其有合法用途,请确保将初始化委托给链上:

class Suite_Edit_AutoEntry( unittest.TestCase ):

    def __init__(self, *args, **kwargs):  # Accept all unrecognized args for delegation
        # Delegate to parent initializer
        super().__init__(*args, **kwargs)  # On Py2, super(Suite_Edit_AutoEntry, self)...
        ... do additional initialization here ...

当然,如 cmets 中所述,您可以有单独的类设置(从 Python 2.7/3.2 开始)using setupClass,因此您根本不必处理 __init__ 的挑剔。

【讨论】:

  • 我上面的例子只通过了,但我真正的测试是为数据库做一些准备工作。例如截断一个表并创建一组记录,每个测试都可以执行搜索。我将在 init 和 setUpClass() 上播放/阅读,看看什么更有意义。 TY 的帮助家伙。祝你今晚愉快。抱歉,我已经习惯了 C++,如果你不想要它的功能,我不需要调用基类,而且我有一段时间没有使用 C++,所以也许这也改变了。
  • 好的,上面的 init 方法对我不起作用,但 setUpClass() 方法编译并运行没有错误。剩下的明天我会弄清楚。
  • setupClass 令人困惑,因为它不带实例参数,因此无法在 setupClass 中引用对象实例数据,因此我还发现 init 是执行一次的唯一实用方法-off 对象数据设置。类设计师的意图是什么?
  • @ConradB:它的目的是设置类本身,而不是特定的实例。在类本身上设置属性将只创建一次,并且它们仍然可以通过实例访问(例如,在setupClass 中执行cls.foo = 1 将允许您稍后在实例方法中读取self.foo)。单元测试很奇怪,很少需要担心实例之间的状态泄漏(因为它一开始就没有创建多个实例)。
  • 感谢Shadow的回复,花了我一段时间才掌握。是的,单元测试不应该在每个测试中泄漏,我来自 C++ 背景,所以 Python 类数据感觉类似于静态。我已经决定单元测试中的 classmethods 仅用于按时初始化/拆卸,@classmethod 的其他用途成为测试 anitpattern。
猜你喜欢
  • 2018-05-06
  • 2016-02-03
  • 2013-01-13
  • 1970-01-01
  • 2018-11-15
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多