Python单元测试:由于从同一文件夹导入而失败 [英] Python Unittest: Fail due to import from same folder

查看:137
本文介绍了Python单元测试:由于从同一文件夹导入而失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题看似微不足道,但我无法在网上找到单个答案.这是我的设置:

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:
- - test1.py
- - test2.py
- - __init__.py (empty)

现在,我要跑步

python -m unittest discover

从项目文件夹中.

在test1.py中,我从第一个源文件导入和导入:

In test1.py I import and import from my first source file:

from src.file1 import class1

但是在file1.py中,我是从另一个导入的:

In file1.py however, I import from the other one:

from file2 import class2

如上所述运行单元测试会导致:

Running the unittest as mentioned above results in:

[...]
    from file2 import class2
ModuleNotFoundError: No module named 'file2'

我在做什么错了?

谢谢你,祝你有美好的一天!

Thank you and have a nice day!

推荐答案

您应完全限定进口的资格,即代替:

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

from file2 import class2

使用

from .file2 import class2

from之后注意..

更新:验证:

(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>

请注意,我正在从from src.xxx有意义的目录中运行命令.

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

更新2:注意,Python不能满足直接在子目录中(即作为入口点)运行单个文件的需要. Guido强烈反对这种用法,因此这种情况不太可能改变.尽管您可以解决此问题,但正确的做法非常简单,值得学习.

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.

我们首先将src/file1.py更改为具有main()功能:

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

class class1:
    pass


def main():
    print("hello from main")

注意:我没有添加if __name__=="__main__"部分.

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

从命令行调用此函数的正确方法是使project成为真实"程序包.

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

通过添加setup.py文件来创建真实"包. setup.py文件可以包含很多字段,但是此用例唯一需要的字段如下:

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
        """
    }
)

请注意,setup.py位于project文件夹中.

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 .

注意最后的..

setup.py文件中的entry_points .. console_scripts现在为您创建了一个新的Shell命令:

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

console_scripts行

the console_scripts line

run-file1 = src.file1:main

表示要创建一个名为run-file的shell命令,该命令应执行src.file1中的main函数.

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

这篇关于Python单元测试:由于从同一文件夹导入而失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆