Nosetest初始化错误

3

调用nosetests会给我以下结果:

======================================================================
ERROR: Failure: TypeError (__init__() takes exactly 2 arguments (1 given))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/sheena/WORK/CriticalID/workspace/flow_env2/local/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/loader.py", line 519, in makeTest
    return self._makeTest(obj, parent)
  File "/home/sheena/WORK/CriticalID/workspace/flow_env2/local/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/loader.py", line 578, in _makeTest
    return MethodTestCase(obj)
  File "/home/sheena/WORK/CriticalID/workspace/flow_env2/local/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/case.py", line 345, in __init__
    self.inst = self.cls()
TypeError: __init__() takes exactly 2 arguments (1 given)

除此之外还有其他内容。

我的目录结构如下:

MyStuff
   ./__init__.py
   ./tests
        ./some_tests.py
        ./other_tests.py
        ./ ... lots more
        ./a_useful_group_of_tests
           ./more_tests.py
           ./tasty_tests.py
           ./ ...lots more
   ./other_files_and_directories

现在有很多文件中都有很多测试,而这个错误没有提供任何关于错误来自代码哪部分的提示。你有什么想法可以帮助我找到它吗?到目前为止,我能想到的最好办法就是删除所有测试文件,然后逐个添加回去,但这并不是理想的解决办法。


1
你的测试用例中是否有非默认构造函数?例如 __init__(self, some_param) - Peter Wood
你可以在 nosetests 命令后指定文件名来运行单个测试。我认为你也可以按子目录运行 nosetests,因为它会递归地运行该子目录。这应该有助于限制你正在测试的文件数量。 - user707650
你尝试过增加nose的详细程度吗:-vv和其他变体。也许nose会告诉你足够的信息来推断错误的文件。 - user707650
@PeterWood:所有的东西都是从unittest.TestCase继承而来的。我没有对测试构造函数做任何操作。 - Sheena
@Evert:谢谢。我已经找到引起问题的文件了。稍后我会在我的问题中添加更多细节。 - Sheena
3个回答

3
通常的原因是您在其中一个测试中使用了一个未在其中导入或具有损坏导入的类。或者有一个单独损坏的测试或导入的类,当通过全局鼻子测试用例运行器环境与其他测试初始化时,由于缺少的导入在另一个测试中被导入,所以可以正常工作。 但是,在测试类的初始加载或个别加载时,它会引发找不到或其他错误。但是nose并没有表现得很清楚,尽管它可能显示了类的初始化错误。
因此,在测试环境中使用您的示例代码时,“好东西”中的某些内容在模块初始化时没有传递参数,这些参数对于正确初始化是必需的。但是如果稍后在测试中初始化,则会获得它们。
或者,您意外地在不是测试类的类中调用了test_something方法(例如,在goodies中的某个位置或由其使用的类中),而鼻子发现并初始化它,但未提供必需的参数。
您可以逐个审查导入,将它们放回模块级别,然后在Python shell上初始化问题类来解决它。

1

解决方案:

从脚本顶部删除导入语句。

为什么:

根据Evert的建议,我使用-vv选项执行了nosetests,定位到给我带来问题的测试文件。结果发现错误消息并不是来自于任何特定的测试。也就是说,测试按预期运行,这些错误只是附加到输出中。输出看起来像这样:

Failure: TypeError (__init__() takes exactly 2 arguments (1 given)) ... ERROR
Failure: TypeError (__init__() takes exactly 2 arguments (1 given)) ... ERROR
...
test_clear_instructions (the_calculator2.tests.model_tests.workflow_tests.Workflow_tests) ... 
...all my tests follow

测试用例中唯一没有的是导入语句。所以我只是把它们移到了使用它们的地方。

但为什么会发生这种情况?任何知道答案的人都可以获得额外的分数

再次说明,我不想阅读大量代码来找到答案。


说明性代码:

from my.stuff import goodies    #<----------Error from this line

class My_tests(unittest.TestCase):
    def test_one(self):
        do stuff
    def test_two(self):
        do other stuff

这段代码没有错误:

class My_tests(unittest.TestCase):
    def test_one(self):
        from my.stuff import goodies
        do stuff
    def test_two(self):
        from my.stuff import goodies
        do other stuff

既然您提出了一个新问题,最好是使用这个解决方案更新您当前的问题,并且包括新问题(但不要覆盖旧问题,只需添加即可),或者提出一个全新的问题。否则,您将得到回答一个“答案”而不是所问的问题的答案。 - user707650
你应该展示一个最小化的测试,让人们能够回答这个问题。 - user707650
@Evert:我的问题是如何解决我面临的问题。问题已经解决,因此问题得到了回答。如果有人有比我更好的答案(不仅仅是修复问题,而是说出实际发生的事情),我将很高兴将其标记为正确答案,并可能会点赞,因为这些东西真的很奇怪。我在这里要求的是一个更有用的版本,它比我自己的正确答案更好。 - Sheena

1

我在这个问题上花了太多时间,现在想要回馈。

如果你使用--with-xunit运行nosetests,你会发现故障的测试被记录在路径下nose.failure.Failure.runTest。如果你试图运行该测试,它会说它不存在。这里发生了一些奇怪的事情。

有趣的是,如果你在--collect-only --verbose下运行它,你会得到Failure: TypeError(__ init __()需要精确地2个参数(1个给出))......ok,所以首先有些东西被识别为一个测试,当它可能不应该时失败了。其次,与失败测试相邻的两个包都通过了,因此即使找出哪个文件失败也不是一件简单的事情。

事实证明,有人创建了一个非测试文件,其中的名称中包含test。Nose试图将其解释为测试,因此出现了错误。

可悲的是,我必须手动运行每个包才能找到这个问题。你可以通过find /path/to/package -name "*test*.py,然后grep任何不位于测试目录中的内容来做到这一点。


我遇到过这种情况两次,即运行一个以“test”前缀命名的文件,但该文件不包含任何测试。我使用@nottest修饰这些文件中的类,问题得到了解决。 - Vas Vasanth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接