我试图列出每个遇到的模块中的所有函数来强制编写测试用例。但是,我遇到的问题只是将文件的完整路径作为字符串而不是导入它。当我使用inspect.getmembers(fullpath, inspect.isfunction)
时,它返回一个空数组。有没有办法实现这个目标?到目前为止,这是我的代码:
import glob
import os
import inspect
def count_tests(moduletestdict):
for key,value in moduletestdict.items():
print("Key: {}".format(key))
print(inspect.getmembers(key, inspect.isfunction))
def find_functions(base_dir):
"""moduletestdict has key value pairs where the key is the module
to be tested and the value is the testing module"""
moduletestdict = {}
for roots, dirs, files in os.walk(base_dir):
for f in files:
if (".py" in f) and (".pyc" not in f) and ("test_" not in f) and (f != "__init__.py"):
if "test_{}".format(f) in files:
moduletestdict["{}/{}".format(roots,f)] = "{}/{}".format(roots, "test_{}".format(f))
else:
moduletestdict["{}/{}".format(roots,f)] = "NOTEST"
return moduletestdict
if __name__ == "__main__":
base_dir = "/Users/MyName/Documents/Work/MyWork/local-dev/sns"
moduletestdict = find_functions(base_dir)
count_tests(moduletestdict)
答案 0 :(得分:0)
你确实需要以某种方式导入模块,但“推荐”的方式有点棘手,因为随着新版本的Python不断变化,请参阅this answer。
这是一个基于gorilla library的测试运行器的示例,它与Python 2和Python 3兼容:
import inspect
import os
import sys
def module_iterator(directory, package_dotted_path):
paths = os.listdir(directory)
for path in paths:
full_path = os.path.join(directory, path)
basename, tail = os.path.splitext(path)
if basename == '__init__':
dotted_path = package_dotted_path
elif package_dotted_path:
dotted_path = "%s.%s" % (package_dotted_path, basename)
else:
dotted_path = basename
if os.path.isfile(full_path):
if tail != '.py':
continue
__import__(dotted_path)
module = sys.modules[dotted_path]
yield module
elif os.path.isdir(full_path):
if not os.path.isfile(os.path.join(full_path, '__init__.py')):
continue
__import__(dotted_path)
package = sys.modules[dotted_path]
yield package
for module in module_iterator(full_path, dotted_path):
yield module
def main():
directory_path = '/path/to/your/package'
package_name = 'package'
sys.path.insert(0, directory_path)
modules = module_iterator(directory_path, package_name)
for module in modules:
functions = inspect.getmembers(module, inspect.isfunction)
print("functions for module '{0}': {1}".format(
module.__name__, functions)
)
if __name__ == "__main__":
main()
这里/path/to/your/package
将是包的存储库,即包含自述文件,文档等的目录,就像Python包的情况一样,而package_name
将是存储库中包含根__init__.py
文件的目录名。
实际上,函数module_iterator
也接受其参数package_dotted_path
的模块,例如'package.subpackage.module'
,但之后只会检索此特定模块中的函数。如果传递了一个包,那么将检查所有递归嵌套的模块。