7

在 python setuptools 中,python setup.py test 运行测试套件。但是,如果我的测试套件中有导入错误,我获得的唯一错误消息是 AttributeError 抱怨我的测试类丢失。有没有办法获得更详细的错误消息,所以我可以修复测试套件?

我将通过以下示例更好地解释自己。假设我有一个名为 foo 的包,用 paste 重新创建。然后我添加测试

./foo
./foo/__init__.py
./foo/tests
./foo/tests/__init__.py
./foo/tests/mytest.py
./setup.cfg
./setup.py

现在,假设 mytest.py 包含以下代码

import unittest
class MyTestClass(unittest.TestCase):
    def testFoo(self):
        self.assertEqual(1,1)

这行得通。但是,如果我尝试导入不存在的模块

import unittest
import frombiz
class MyTestClass(unittest.TestCase):
    def testFoo(self):
        self.assertEqual(1,1)

这是我得到的错误

Traceback (most recent call last):
  File "setup.py", line 26, in <module>
    test_suite = "foo.tests"
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/core.py", line 152, in setup
    dist.run_commands()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/dist.py", line 975, in run_commands
    self.run_command(cmd)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/dist.py", line 995, in run_command
    cmd_obj.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/setuptools/command/test.py", line 121, in run
    self.with_project_on_sys_path(self.run_tests)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/setuptools/command/test.py", line 101, in with_project_on_sys_path
    func()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/setuptools/command/test.py", line 130, in run_tests
    testLoader = loader_class()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 816, in __init__
    self.parseArgs(argv)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 843, in parseArgs
    self.createTests()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 849, in createTests
    self.module)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 613, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 587, in loadTestsFromName
    return self.loadTestsFromModule(obj)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/setuptools/command/test.py", line 34, in loadTestsFromModule
    tests.append(self.loadTestsFromName(submodule))
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 584, in loadTestsFromName
    parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'mytest'

换句话说,没有提到失败的导入。

4

4 回答 4

3

鼻子。无需修改您的代码。做就是了:

$ pip install nose
$ nosetests

如果有 ImportError,您将看到它:

ERROR: Failure: ImportError (cannot import name MyModel)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/garyvdm/bwreport/ve/lib/python3.2/site-packages/nose/failure.py", line 37, in runTest
    raise self.exc_class(self.exc_val).with_traceback(self.tb)
  File "/home/garyvdm/bwreport/ve/lib/python3.2/site-packages/nose/loader.py", line 390, in loadTestsFromName
    addr.filename, addr.module)
  File "/home/garyvdm/bwreport/ve/lib/python3.2/site-packages/nose/importer.py", line 39, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/home/garyvdm/bwreport/ve/lib/python3.2/site-packages/nose/importer.py", line 86, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/home/garyvdm/bwreport/bwreport/daemon/__init__.py", line 11, in <module>
    from bwreport.models import (
ImportError: cannot import name MyModel
于 2012-03-01T09:42:23.560 回答
1

问题是第一个参数__import__()必须是模块。当您需要访问带有点名称的对象时,您永远不知道什么是模块,什么不是。获取module.subname对象的一种方法是首先尝试将其作为子模块导入,当它失败时使用getattr(module, subname),也是unittest如此。这有时会给你AttributeError而不是ImportError. 另一种方法是先尝试getattr(module, subname),并且仅在失败时尝试导入。这种方式并不好:它有时会ImportError在更合适的时候给你AttributeError

在这种情况下,最好的unittest办法可能是引发它自己的异常,说导入和属性查找都失败了。尝试发送此问题的错误报告。

于 2009-11-30T13:34:58.927 回答
0

The issue here is that a Python ImportError doesn't tell you what module the error actually occurred in, unless you carefully inspect the traceback -- which the unittest module doesn't do. You'll have the same problem with the unittest module, regardless of what tool you use to run it.

You may want to try the "nose" package - it has a setuptools plugin, so you can add it to your setup.py and let it find and import your tests, instead of using setuptools' default test finder. If I recall correctly, it loads test code in a different way than unittest does, and it may be able to give a better error message in this case. And even if it doesn't, it'd probably be easier to get it added to nose than to unittest!

于 2010-01-29T18:10:34.907 回答
0

您可能还想使用Distribute尝试您的代码(setuptools 的一个分支,因为 setuptools 没有得到非常积极的维护)。我不知道它是否会有所不同,但值得一试。

于 2009-11-30T13:41:41.643 回答