Skip to content Skip to sidebar Skip to footer

Python Unittest: Fail Due To Import From Same Folder

the question seems pretty trivial, but I could not find a single answer to it online. Heres my setup: project: - src: - - __init__.py (empty) - - file1.py - - file2.py - test: - -

Solution 1:

You should fully qualify your imports, i.e. instead of:

from file2 import class2

use

from .file2import class2

notice the . after from.

Update: verification:

(dev) go|c:\srv\tmp\unttst\project> tree
.
|-- src
||-- __init__.py
||-- file1.py
|   `-- file2.py
`-- test
    |-- __init__.py
    `-- test1.py

2 directories, 5 files

(dev) go|c:\srv\tmp\unttst\project> type src\file1.py

from .file2 import Class2

class class1:
    pass

(dev) go|c:\srv\tmp\unttst\project> type src\file2.py


class Class2:
    pass

(dev) go|c:\srv\tmp\unttst\project> type test\test1.py

from src.file1 import class1

(dev) go|c:\srv\tmp\unttst\project> python -m unittest discover

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

(dev) go|c:\srv\tmp\unttst\project>

Notice that I'm running the command from a directory where from src.xxx makes sense.

Update 2: Note, Python does not cater to running individual files in a subdirectory directly (i.e. as an entry point). Guido is strongly against such usage so this is unlikely to change. While you can hack your way around this, doing it the right way is very simple and worth learning.

Let's first change src/file1.py to have a main() function:

(dev) go|c:\srv\tmp\unttst\project> cat src\file1.py

from .file2 import Class2

classclass1:
    passdefmain():
    print("hello from main")

Note: I'm not adding a if __name__=="__main__" section.

The right way of calling this function from the command line is to make project a "real" package.

A "real" package is created by adding a setup.py file. setup.py files can contain a lot of fields, but the only ones needed for this use-case are as follows:

(dev) go|c:\srv\tmp\unttst\project> cat setup.py

from setuptools import setup

setup(
    name="myproject",
    entry_points={
        'console_scripts': """
            run-file1 = src.file1:main
        """
    }
)

note that setup.py lives in the project folder.

Next you install your package in "development" mode:

(dev) go|c:\srv\tmp\unttst\project> pip install -e .

notice the . at the end.

The entry_points .. console_scripts in the setup.py file has now created a new shell command for you:

(dev) go|c:\srv\tmp\unttst\project> run-file1
hello from main

the console_scripts line

run-file1 = src.file1:main

says to create a shell command named run-file which should execute the main function found in src.file1.

Post a Comment for "Python Unittest: Fail Due To Import From Same Folder"