Python 单元测试加载程序在 __init__() 调用期间抛出 TypeError
Python unittest loader throws TypeError during an __init__() call
我已经为我的 Python 应用程序编写了一堆测试,但它们突然似乎不再正常工作!
我在 tests
模块中创建了一堆测试:
在 tests.__main__.py
中,我包含了以下代码来加载我的测试套件:
import unittest
if __name__ == "__main__":
loader = unittest.TestLoader()
start_dir = "."
suite = loader.discover(start_dir=start_dir, pattern='*_test.py')
runner = unittest.TextTestRunner()
runner.run(suite)
我知道我听起来像个菜鸟,但大约一个小时前,这些测试对我来说还算完美。我会通过从我的基本目录中键入 python3 -m tests
来发布它们。但是,我现在收到了一个非常 st运行ge TypeError
:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/yuchen/Desktop/myproj/myapp/tests/__main__.py", line 6, in <module>
suite = loader.discover(start_dir=start_dir, pattern='*_test.py')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 341, in discover
tests = list(self._find_tests(start_dir, pattern))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 406, in _find_tests
yield from self._find_tests(full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 406, in _find_tests
yield from self._find_tests(full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 398, in _find_tests
full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 452, in _find_test_path
return self.loadTestsFromModule(module, pattern=pattern), False
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 123, in loadTestsFromModule
tests.append(self.loadTestsFromTestCase(obj))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 92, in loadTestsFromTestCase
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/suite.py", line 24, in __init__
self.addTests(tests)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/suite.py", line 57, in addTests
for test in tests:
TypeError: __init__() takes 0 positional arguments but 2 were given
我已经跟踪堆栈跟踪到我认为是导致问题的适当文件,unittest
:
的 suite.py
文件
"""TestSuite"""
import sys
from . import case
from . import util
__unittest = True
def _call_if_exists(parent, attr):
func = getattr(parent, attr, lambda: None)
func()
class BaseTestSuite(object):
"""A simple test suite that doesn't provide class or module shared fixtures.
"""
_cleanup = True
def __init__(self, tests=()):
self._tests = []
self._removed_tests = 0
print("Tests", tests) # <--- this was added by me
self.addTests(tests)
但是,__init__()
签名似乎不需要 0 个位置参数。而且,它显然正在执行,因为我在上面的代码中添加了 print("Tests", tests)
之后,在抛出错误之前我看到了以下输出:
Tests: []
Tests: <map object at 0x11033c0b8>
Tests: <map object at 0x11033c0b8>
Tests: <map object at 0x11033c0b8>
Tests: [<unittest.suite.TestSuite tests=[... a list of my tests]]
Tests: <map object at 0x110483978>
Tests: <map object at 0x110483978>
Traceback (most recent call last):
我对发生的事情一头雾水。堆栈跟踪中打印的错误似乎与我在源代码中看到的完全不一致。
编辑(分辨率):
被接受的答案是正确的。我已经编写了另一个测试 class,并决定简单地为 __init__
方法添加一个存根:
class MyUnfinishedTest(BaseTest):
def __init__():
pass
然后我忘记了它并从事其他工作,运行 测试。那是我开始看到我的错误的时候。从我的测试模块中删除这个 class 后,测试 运行 顺利。
回溯看起来有点混乱的原因之一是行:
for test in tests
实际上是在调用一个生成器,它正在运行中发现并加载测试。
所以我猜这是:
TypeError: __init__() takes 0 positional arguments but 2 were given
实际上意味着发现过程找到了一个无法加载的测试class,可能是因为 class 有自己的 __init__
方法,其参数数量与发现的不同期待。
我会仔细检查您的测试 classes 是否有 __init__
方法,并且可能还会更改此行:
start_dir = "."
至:
start_dir = os.path.dirname(__file__)
这意味着发现过程将从 tests
文件夹向下查找,这比“.”更安全。 (当前工作目录)因为当前工作目录可能会根据您开始测试的位置而改变(并且可能最终会选择您不期望的测试)。
我已经为我的 Python 应用程序编写了一堆测试,但它们突然似乎不再正常工作!
我在 tests
模块中创建了一堆测试:
在 tests.__main__.py
中,我包含了以下代码来加载我的测试套件:
import unittest
if __name__ == "__main__":
loader = unittest.TestLoader()
start_dir = "."
suite = loader.discover(start_dir=start_dir, pattern='*_test.py')
runner = unittest.TextTestRunner()
runner.run(suite)
我知道我听起来像个菜鸟,但大约一个小时前,这些测试对我来说还算完美。我会通过从我的基本目录中键入 python3 -m tests
来发布它们。但是,我现在收到了一个非常 st运行ge TypeError
:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/yuchen/Desktop/myproj/myapp/tests/__main__.py", line 6, in <module>
suite = loader.discover(start_dir=start_dir, pattern='*_test.py')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 341, in discover
tests = list(self._find_tests(start_dir, pattern))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 406, in _find_tests
yield from self._find_tests(full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 406, in _find_tests
yield from self._find_tests(full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 398, in _find_tests
full_path, pattern, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 452, in _find_test_path
return self.loadTestsFromModule(module, pattern=pattern), False
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 123, in loadTestsFromModule
tests.append(self.loadTestsFromTestCase(obj))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 92, in loadTestsFromTestCase
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/suite.py", line 24, in __init__
self.addTests(tests)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/suite.py", line 57, in addTests
for test in tests:
TypeError: __init__() takes 0 positional arguments but 2 were given
我已经跟踪堆栈跟踪到我认为是导致问题的适当文件,unittest
:
suite.py
文件
"""TestSuite"""
import sys
from . import case
from . import util
__unittest = True
def _call_if_exists(parent, attr):
func = getattr(parent, attr, lambda: None)
func()
class BaseTestSuite(object):
"""A simple test suite that doesn't provide class or module shared fixtures.
"""
_cleanup = True
def __init__(self, tests=()):
self._tests = []
self._removed_tests = 0
print("Tests", tests) # <--- this was added by me
self.addTests(tests)
但是,__init__()
签名似乎不需要 0 个位置参数。而且,它显然正在执行,因为我在上面的代码中添加了 print("Tests", tests)
之后,在抛出错误之前我看到了以下输出:
Tests: []
Tests: <map object at 0x11033c0b8>
Tests: <map object at 0x11033c0b8>
Tests: <map object at 0x11033c0b8>
Tests: [<unittest.suite.TestSuite tests=[... a list of my tests]]
Tests: <map object at 0x110483978>
Tests: <map object at 0x110483978>
Traceback (most recent call last):
我对发生的事情一头雾水。堆栈跟踪中打印的错误似乎与我在源代码中看到的完全不一致。
编辑(分辨率):
被接受的答案是正确的。我已经编写了另一个测试 class,并决定简单地为 __init__
方法添加一个存根:
class MyUnfinishedTest(BaseTest):
def __init__():
pass
然后我忘记了它并从事其他工作,运行 测试。那是我开始看到我的错误的时候。从我的测试模块中删除这个 class 后,测试 运行 顺利。
回溯看起来有点混乱的原因之一是行:
for test in tests
实际上是在调用一个生成器,它正在运行中发现并加载测试。
所以我猜这是:
TypeError: __init__() takes 0 positional arguments but 2 were given
实际上意味着发现过程找到了一个无法加载的测试class,可能是因为 class 有自己的 __init__
方法,其参数数量与发现的不同期待。
我会仔细检查您的测试 classes 是否有 __init__
方法,并且可能还会更改此行:
start_dir = "."
至:
start_dir = os.path.dirname(__file__)
这意味着发现过程将从 tests
文件夹向下查找,这比“.”更安全。 (当前工作目录)因为当前工作目录可能会根据您开始测试的位置而改变(并且可能最终会选择您不期望的测试)。