Home > Software design >  Is there a way of unit testing what imports are used?
Is there a way of unit testing what imports are used?

Time:03-07

Is there a way of unit testing what modules are imported in a Python file (a bit like ArchUnit in Java)? The context is in implementing a hexagonal architecture and wanting to ensure that the domain model does not import any code that resides in an adapter. I'd like unit tests to fail if there are forbidden imports.

For example, I might like to test that no modules within foo.bar.domain import anything from foo.bar.adapter. Imports of foo.bar.domain should be allowed from within foo.bar.adapter.

Is this possible in Python and what's the best way of achieving this?

CodePudding user response:

I am not aware that testing methods exist for this specific case, but someone might know more about it. One thing that comes to mind are try-catch with the methods from the other module being checked if you can call a method. Another hacky way, would be to add custom string constants in global context of the each module, and if they are exist you know that the submodule imported/used the other module.

Check more on this stack overflow post.

CodePudding user response:

You can use the -Ximporttime Python flag to trace imports. I'm not entirely sure what would be the logic for finding forbidden imports in your case, but here's a silly example script that might help:

import subprocess
import sys

process = subprocess.run(
    ('python3', '-Ximporttime', '-c', 'import '   'shlex'),
        stdout=subprocess.DEVNULL,
        stderr=subprocess.PIPE,
        encoding='utf-8',
    )

blacklisted_imports = {'enum', 're', 'zipfile'}

data = [
    x.rpartition('|')[2].strip() for x in process.stderr.split('\n')
]
for import_ in data:
    if import_ in blacklisted_imports:
        print('found bad import:', import_)

Output:

found bad import: enum
found bad import: re
  • Related