Python在主代码中调用本地函数会破坏测试的导入吗?

时间:2018-08-26 22:55:57

标签: python python-3.x pytest

我到了Python的导入系统为止...以为我终于有了可靠的东西,然后莫名其妙的事情发生了!

这是我的应用程序的目录结构:

/
- my-application/
 - subpackage/
  - __init__.py
  - my_module.py
 - __init__.py
- tests/
 - subpackage/
  - __init__.py
  - test_my_module.py
 - __init__.py
 - conftest.py
 - run.py
 - spark.py

我通过tests/run.py运行所有测试,如下所示(试图解决所有导入问题):

import os
import pytest
import sys

rootdir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))

sys.path.insert(0, os.path.abspath(os.path.join(rootdir, "my-application")))

sys.exit(pytest.main([os.path.join(rootdir, "tests")]))

这就像一个绝对的魅力,直到我对文件/my-application/subpackage/my-module.py进行了一次修改-我添加了一个本地函数调用。所以例如my_module.py:

def foo():
  pass

def run_my_module():
  def bar():
    foo()          <---- Added this line

  bar()
  print("Ran")

更新:可以正常工作:

def foo():
  pass

def run_my_module():
  def bar():
    pass

  foo()
  bar()
  print("Ran")

一旦我添加了本地函数调用,测试就会停止工作,并显示错误No module named "subpackage"

test_my_module.py(基本上)如下所示:

from subpackage.my_module import run_my_module

def basic_test():
    run_my_module()

请注意,在test_my_module.py中,我将subpackage用作导入语句的第一部分,因为我正在使用将run.py设置为系统路径的my-application文件。如果我将导入更改为以my_application开头,则会出现与my_application.py相同的错误。

我仍在学习python,因此建议您对我喜欢的应用程序结构进行任何更改。我简直不敢相信这个导入系统的麻烦-我确实觉得我在这里缺少一些基本的东西...

提前谢谢!

1 个答案:

答案 0 :(得分:1)

手动管理导入路径很困难。
setup.py是管理python软件包的最佳方法。

按惯例,程序包名称应使用_而不是-

使用setup.py旁边的内容创建一个my_application/

from setuptools import find_packages, setup

setup(
    name='my_application',
    version='0.0.1',
    packages=find_packages(),
)

我建议使用类似以下的应用程序结构:

$ tree

├── my_application
│   ├── __init__.py
│   ├── spark.py
│   └── subpackage
│       ├── __init__.py
│       └── my_module.py
├── setup.py
└── tests
    ├── conftest.py
    └── subpackage
        ├── __init__.py
        └── test_my_module.py

在本地安装软件包

python setup.py develop 这将符号链接(魔术地)将您的软件包安装到python软件包路径中
现在,在任何脚本中,您都可以按预期使用路径,例如

from my_application.subpackage.my_module import run_my_module

还建议您使用virtualenv

有关setup.py here

的更多信息