Stan
Stan

Reputation: 38255

Python runtime determine which module to load

I have my Python unittest script like below. It takes an argument '-a' to determine whether the testcases should load the base module from foo_PC_A.py or foo_PC_B.py. I use shutil.move() to rename either .py file to foo.py, so all the testcase modules (e.g. tm1.py, tm2.py) can simply import foo. Though this looks like a workaround and not Pythonic. Is there any better way to do this? Or a better design to fundamentally resolve this issue.

(run_all_unittest.py)

if sys.argv[1] = '-a':
  shutil.move('foo_PC_A.py', 'foo.py')
else:
  shutil.move('foo_PC_B.py', 'foo.py')


test_module_list = ['tm1', 'tm2', ...]
for test_module_name in test_module_list:
  test_module = __import__(test_module_name)
  test_suites.append(unittest.TestLoader().loadTestsFromModule(test_module))

alltests = unittest.TestSuite(test_suites)
unittest.TextTestRunner().run(alltests)

if sys.argv[1] = '-a':
  shutil.move('foo.py', 'foo_PC_A.py')
else:
  shutil.move('foo.py', 'foo_PC_B.py')

(tm1.py)

from foo import MyTestCase
...

(foo_PC_A.py)

import <some module only available on PC A>

class MyTestCase(unittest.TestCase):
...

(foo_PC_B.py)

# since the PC A modules are not available on PC B, 
# just call the pre-built executable via subprocess
import subprocess
class MyTestCase(unittest.TestCase):
...
  def test_run(self):
        subprocess.call(...)

Upvotes: 0

Views: 46

Answers (1)

augustomen
augustomen

Reputation: 9739

You can fool Python into thinking the module has already been loaded. Just import the module dynamically and use sys.modules:

import sys
import importlib

if sys.argv[1] = '-a':
    sys.modules['foo'] = importlib.import_module('foo_PC_A')
else:
    sys.modules['foo'] = importlib.import_module('foo_PC_A')

When any module runs import foo or from foo import ..., Python will use that path.

Note that if foo is moved to a package, the full Python path must be specified, as in:

sys.modules['path.to.foo'] = ...

Upvotes: 1

Related Questions