我的项目结构如下:
package
-- tests
-- bin
-- subpackage
-- ...py
我需要测试一个名为master_disaster()
的函数,它存在于bin/let-me-out
内(是-
)。 let-me-out
是一个可执行的.py
文件,我的文件夹中没有setup.py
个文件或类似文件。
如何在测试中导入此功能?我的测试将是一个简单的工具,用以下方式检查时间:
@pytest.fixture
def now():
return timezone.now()
然后使用now()
函数创建一个let-me-out
将在特定时间后删除的新文件。所有这些都是Python 2.7。
答案 0 :(得分:2)
首先,破折号将let-me-out
单词变为Python中的无效标识符。要解决它,你必须调用imp
(Python 2.7)
或importlib
(Python 3.5+)机制。
以下是导入具有限定名称let_me_out
但使用bin/let-me-out
作为源文件的新模块的示例:
import importlib
def test_master_disaster():
loader = importlib.machinery.SourceFileLoader('let_me_out', 'bin/let-me-out')
spec = importlib.util.spec_from_loader(loader.name, loader)
let_me_out = importlib.util.module_from_spec(spec)
loader.exec_module(let_me_out)
# this is only a stub, to show an example of calling the master_disaster function
assert let_me_out.master_disaster() == 'spam'
您可以将此代码提取到灯具中以使其可重复使用:
import importlib
import pytest
@pytest.fixture(scope='session')
def let_me_out():
loader = importlib.machinery.SourceFileLoader('let_me_out', 'bin/let-me-out')
spec = importlib.util.spec_from_loader(loader.name, loader)
let_me_out = importlib.util.module_from_spec(spec)
loader.exec_module(let_me_out)
return let_me_out
def test_master_disaster(let_me_out):
assert let_me_out.master_disaster() == 'spam'
使用Python 2.7,事情变得更加容易:
import imp
import pytest
@pytest.fixture(scope='session')
def let_me_out():
return imp.load_source('let_me_out', 'bin/let-me-out')
def test_master_disaster(let_me_out):
assert let_me_out.master_disaster() == 'spam'