I am trying to create a pytest
for a Python 2.x script executable with dashes included in its name. I tried to import it the usual way but I can't figure out how to make it work with the dashes.
My project structure is as follows:
package
-- tests
-- bin
-- subpackage
-- ...py
Specifically, I need to test a function called master_disaster()
which exists inside bin/let-me-out
(yes with -
). let-me-out
is an executable .py
file and my folder has no setup.py
file or anything similar.
How can I import this function inside my test? My test is going to be a simple fixture that checks the time with:
@pytest.fixture
def now():
return timezone.now()
It then uses the now()
function to create a new file which let-me-out
will delete after a specific amount of time.
First of all, dashes make let-me-out
word to an invalid identifier in Python. To work around it, you have to invoke the imp
(Python 2.7) or importlib
(Python 3.5+) machinery.
Here is an example of importing a new module having a qualified name let_me_out
, but using bin/let-me-out
as source file:
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'
You can extract this code into a fixture to make it reusable:
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'
Things are even easier with 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'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.