简体   繁体   中英

How can I get module name automatically from __init__.py or conftest.py?

I am running multiple tests in a tests package, and I want to print each module name in the package, without duplicating code. So, I wanted to insert some code to __init__.py or conftest.py that will give me the executing module name. Let's say my test modules are called: checker1, checker2, etc...

My directory structure is like this:

tests_dir/
├── __init__.py
├── conftest.py
├── checker1
├── checker2
└── checker3

So, inside __init__.py I tried inserting:

def module_name():
    return os.path.splitext(__file__)[0]

But it still gives me __init__.py from each file when I call it.

I also tried using a fixture inside conftest.py, like:

@pytest.fixture(scope='module')
def module_name(request):
    return request.node.name

But it seems as if I still need to define a function inside each module to get module_name as a parameter.

What is the best method of getting this to work?

Edit:

In the end, what I did is explained here:

conftest.py

@pytest.fixture(scope='module', autouse=True)
def module_name(request):
    return request.node.name

example for a test file with a test function. The same needs to be added to each file and every function:

checker1.py

from conftest import *

def test_columns(expected_res, actual_res, module_name):
    expected_cols = expected_res.columns
    actual_cols = actual_res.columns

    val = expected_cols.difference(actual_cols)  # verify all expected cols are in actual_cols
    if not val.empty:
        log.error('[{}]: Expected columns are missing: {}'.format(module_name, val.values))
    assert val.empty

Notice the module_name fixture I added to the function's parameters.

  • expected_res and actual_res are pandas Dataframes from excel file.
  • log is a Logger object from logging package

In each module (checker1, checker2, checker3, conftest.py), in the main function, execute

print(__name__)

When the __init__.py file imports those packages, it should print the module name along with it.

Based on your comment, you can perhaps modify the behaviour in the __init__.py file for local imports.

__init.py__

import sys, os
sys.path.append(os.path.split(__file__)[0])

def my_import(module):
    print("Module name is {}".format(module))
    exec("import {}".format(module))

testerfn.py

print(__name__)
print("Test")

Directory structure

tests_dir/
├── __init__.py
└── testerfn.py

Command to test

import tests_dir
tests_dir.my_import("testerfn")

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM