unittest,在本地工作,但不在远程服务器上工作,没有名为 x.__main__ 的模块; 'x'是一个包,不能直接执行
unittest, works locally, but not on a remote server, no module named x.__main__; 'x' is a package and cannot be directly executed
我正在为我的 Python 包开发 Jenkins CI/CD 管道。我的项目文件层次结构如下:
project/
- package_name
- file1.py
- file2.py
- etc...
- tests
- unit
- __main__.py
- __init__.py
- test1.py
- test2.py
所有单元测试(我正在使用 unittest
)都是 运行 使用单个命令
python -m tests.unit
通过添加 __init__.py
以下内容:
内容
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
和 __main__.py
看起来像这样
内容
import unittest
import sys
sys.path.append('../..')
loader = unittest.TestLoader()
start_dir = '.'
suite = loader.discover(start_dir)
runner = unittest.TextTestRunner(verbosity=2).run(suite)
首先,路径更改为./tests/unit
。之后,将顶层目录添加到导入路径中,以便可以在测试中导入包。这在我的个人笔记本电脑 (Python 3.6.4) 上按预期工作(即,所有休息由项目目录顶部的 运行ning python -m test.unit
执行)。
但是,当我在远程 Jenkins 服务器(Python 3.6.4)上使用相同的技巧时,我收到以下错误:
no module named test.unit.__main__; 'test.unit' is a package and cannot be directly executed
我已经研究了这个问题,但是 none 提议的解决方案似乎适用于我的情况。
我如何修改我的代码以在 unittest
中创建一个测试套件,这将 运行 在本地和远程没有任何问题?
编辑
我尝试修改 PYTHONPATH
变量,但没有成功
我可以 运行 使用此命令进行测试:
python -m unittest discover
您永远不需要 运行 os.chdir
或附加到 sys.path
只是为了 运行 您的测试。
我复制了你的项目结构,像这样:
.
├── package
│ └── module.py
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_module.py
请注意 tests/
下的每个目录都有一个 __init__.py
文件,该文件实际上是空的。它只需要存在。它的存在使该目录成为一个模块。有关更多用例,请阅读此 answer.
你不需要 __main__.py
。那是当你想从命令行 运行 python3 -m package
时(而不是 python3 package/module.py
或类似的东西)。看到这个 answer.
在这种情况下,unittest 只需要测试目录中的 __init__.py
文件即可正常工作。
每个测试文件的名称以 test_
开头也很重要,因为这是 unittest 查找的命名约定。
作为参考,module.py
的内容如下所示:
def method():
return True
test_module.py
的内容如下所示:
from package.module import method
from unittest import TestCase
class TestMethod(TestCase):
def test_method(self):
self.assertTrue(method())
对您的代码进行这些修改将使您能够 运行 在 unittest 中测试套件,而不会在本地和远程出现任何问题。
1。为什么它不起作用?
1.1。关于 python -m
和 __main__.py
当你 运行 python -m tests.unit
时,python 解释器 运行 的代码是这样的
tests.__init__.py
tests.unit.__init__.py
tests.unit.__main__.py
1.2。重现错误
现在,如果您删除 __main__.py
,您将收到以下错误:
No module named tests.unit.__main__; 'tests.unit' is a package and cannot be directly executed
这与您收到的消息几乎相同。如果您的 sys.path
中有一个文件夹,其中包含名为 test
的文件夹,其结构如下(注意:test
文件夹不在 prular 中,并且没有 __main__.py !)
test
├── __init__.py
└── unit
└── __init__.py
和运行命令
python -m test.unit
python 解释器尝试 运行 的顺序是
test.__init__.py
test.unit.__init__.py
test.unit.__main__.py <-- missing!
由于缺少 test.unit.__main__.py
,您将收到错误消息
No module named test.unit.__main__; 'test.unit' is a package and cannot be directly executed
这是您收到的错误消息。因此,您的错误消息的原因很可能是,您在 sys.path
目录中的某处有一个名为 test
的目录,其结构如上所示,并且您正在尝试调用 python -m test.unit
而不是python -m tests.unit
.
2。如何让它发挥作用?
- 删除您在
__init__.py
和 __main__.py
中使用的 os.chdir
和 sys.path.append
技巧。至少,python unittest 工作不需要它们。
- 使用 documentation 中显示的模式创建单元测试(通过子类化 unittest.TestCase)
- 运行 你的单元测试
python -m unittest
我正在为我的 Python 包开发 Jenkins CI/CD 管道。我的项目文件层次结构如下:
project/
- package_name
- file1.py
- file2.py
- etc...
- tests
- unit
- __main__.py
- __init__.py
- test1.py
- test2.py
所有单元测试(我正在使用 unittest
)都是 运行 使用单个命令
python -m tests.unit
通过添加 __init__.py
以下内容:
内容
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
和 __main__.py
看起来像这样
内容
import unittest
import sys
sys.path.append('../..')
loader = unittest.TestLoader()
start_dir = '.'
suite = loader.discover(start_dir)
runner = unittest.TextTestRunner(verbosity=2).run(suite)
首先,路径更改为./tests/unit
。之后,将顶层目录添加到导入路径中,以便可以在测试中导入包。这在我的个人笔记本电脑 (Python 3.6.4) 上按预期工作(即,所有休息由项目目录顶部的 运行ning python -m test.unit
执行)。
但是,当我在远程 Jenkins 服务器(Python 3.6.4)上使用相同的技巧时,我收到以下错误:
no module named test.unit.__main__; 'test.unit' is a package and cannot be directly executed
我已经研究了这个问题,但是 none 提议的解决方案似乎适用于我的情况。
我如何修改我的代码以在 unittest
中创建一个测试套件,这将 运行 在本地和远程没有任何问题?
编辑
我尝试修改 PYTHONPATH
变量,但没有成功
我可以 运行 使用此命令进行测试:
python -m unittest discover
您永远不需要 运行 os.chdir
或附加到 sys.path
只是为了 运行 您的测试。
我复制了你的项目结构,像这样:
.
├── package
│ └── module.py
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_module.py
请注意 tests/
下的每个目录都有一个 __init__.py
文件,该文件实际上是空的。它只需要存在。它的存在使该目录成为一个模块。有关更多用例,请阅读此 answer.
你不需要 __main__.py
。那是当你想从命令行 运行 python3 -m package
时(而不是 python3 package/module.py
或类似的东西)。看到这个 answer.
在这种情况下,unittest 只需要测试目录中的 __init__.py
文件即可正常工作。
每个测试文件的名称以 test_
开头也很重要,因为这是 unittest 查找的命名约定。
作为参考,module.py
的内容如下所示:
def method():
return True
test_module.py
的内容如下所示:
from package.module import method
from unittest import TestCase
class TestMethod(TestCase):
def test_method(self):
self.assertTrue(method())
对您的代码进行这些修改将使您能够 运行 在 unittest 中测试套件,而不会在本地和远程出现任何问题。
1。为什么它不起作用?
1.1。关于 python -m
和 __main__.py
当你 运行 python -m tests.unit
时,python 解释器 运行 的代码是这样的
tests.__init__.py
tests.unit.__init__.py
tests.unit.__main__.py
1.2。重现错误
现在,如果您删除 __main__.py
,您将收到以下错误:
No module named tests.unit.__main__; 'tests.unit' is a package and cannot be directly executed
这与您收到的消息几乎相同。如果您的 sys.path
中有一个文件夹,其中包含名为 test
的文件夹,其结构如下(注意:test
文件夹不在 prular 中,并且没有 __main__.py !)
test
├── __init__.py
└── unit
└── __init__.py
和运行命令
python -m test.unit
python 解释器尝试 运行 的顺序是
test.__init__.py
test.unit.__init__.py
test.unit.__main__.py <-- missing!
由于缺少 test.unit.__main__.py
,您将收到错误消息
No module named test.unit.__main__; 'test.unit' is a package and cannot be directly executed
这是您收到的错误消息。因此,您的错误消息的原因很可能是,您在 sys.path
目录中的某处有一个名为 test
的目录,其结构如上所示,并且您正在尝试调用 python -m test.unit
而不是python -m tests.unit
.
2。如何让它发挥作用?
- 删除您在
__init__.py
和__main__.py
中使用的os.chdir
和sys.path.append
技巧。至少,python unittest 工作不需要它们。 - 使用 documentation 中显示的模式创建单元测试(通过子类化 unittest.TestCase)
- 运行 你的单元测试
python -m unittest