为什么import *不运行导入的代码?

时间:2012-03-15 11:21:19

标签: python unit-testing import

我有一个包含所有单元测试的文件夹。它们都包括:

if __name__ ==  '__main__':
    unittest.TextTestRunner(verbosity=2).run(suite())

因此,为了测试它们,我只需要导入测试脚本。我有一个test_all脚本,通过逐个导入它们来完成所有的单元测试。目前看起来像这样:

from pyMS.test import test_baseFunctions
from pyMS.test import test_compareFeatureXMLmzML
from pyMS.test import test_config
from pyMS.test import test_featureFunctions
from pyMS.test import test_fileHandling
from pyMS.test import test_mzmlFunctions
from pyMS.test import test_output
from pyMS.test import test_parseFeatureXML
from pyMS.test import test_rFunctions
from pyMS.test import test_rPlots
[...]

这意味着每次添加或删除新测试时,我都需要更改导入。所以我想使用

from pyMS.test import *

但是,这不会运行任何代码。我很好奇导入*不运行代码的原因。 此外,如果有人知道一个解决方案(即注意鼻子)来运行所有单元测试而不必逐个导入它们就会很棒。

感谢
NIEK

3 个答案:

答案 0 :(得分:1)

如果使用python 2.7,则可以使用命令行:

python -m unittest discover

这将自动查找并执行所有子目录中的所有测试。有关更多选项,请参阅:

python -m unittest -h

此模块已被移植到python 2.3+,可以下载here。如果你使用backport,那里有一个名为unit2或unit2.py(你的选择)的包含命令行脚本,调用如下:

unit2.py discover

对于from XXX import *,这实际上导入了文件XXX/__init__.py的命名空间中的所有内容。将以下代码放在__init__.py中以自动加载任何直接子模块:

import os

all_files = os.listdir(os.path.dirname(__file__))
modules = [x for x in all_files if x.endswith(".py") and not x.startswith("_")]
__all__ = [x.rpartition(".")[0] for x in modules]

有关其工作原理的详细说明,请参阅python docs for the __all__ global variable

答案 1 :(得分:1)

运行所有测试的最简单方法(不使用外部工具)可能是使用TestLoader.discover

答案 2 :(得分:1)

对于解释器正在读取的初始python文件,

__name__仅设置为"__main__"。这允许在执行if __name__ == "__main__":之后,在没有代码的情况下由其他模块导入模块。

任何不受if __name__ == "__main__":保护的代码都将被执行。因此,您可以在每个文件中删除它,然后在执行导入时unittest.TextTestRunner(verbosity=2).run(suite())将被执行。

更好的方法是使用unittest.TestLoader()中的方法将测试加载到套件中,然后将该套件提供给unittest.TextTestRunner。然后,可以自动加载加载程序,而无需更改测试文件中的导入。将测试文件添加到目录结构中,测试将自动执行。