簡體   English   中英

unittest,在本地工作,但不在遠程服務器上,沒有名為 x.__main__ 的模塊; 'x' 是 package,不能直接執行

[英]unittest, works locally, but not on a remote server, no module named x.__main__; 'x' is a package and cannot be directly executed

我正在為我的 Python package 開發 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 之后,將頂層目錄添加到導入路徑,以便可以在測試中導入 package。 這可以在我的個人筆記本電腦(Python 3.6.4)上按預期工作(即,所有其余部分都是通過在項目目錄頂部運行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

我已經研究過這個問題,但建議的解決方案似乎都不適用於我的情況。

如何修改我的代碼以在unittest中創建一個測試套件,該套件將在本地和遠程運行而不會出現任何問題?

編輯我嘗試修改PYTHONPATH變量,但沒有成功

我可以使用以下命令運行測試:

python -m unittest discover

你永遠不需要運行os.chdir或 append 到sys.path來運行你的測試。

我復制了您的項目結構,如下所示:

.
├── package
│   └── module.py
└── tests
    ├── __init__.py
    └── unit
        ├── __init__.py
        └── test_module.py

注意tests/下的每個目錄都有一個__init__.py文件,該文件實際上是空的。 它只需要存在。 它的存在使該目錄成為一個模塊。 有關更多用例,請閱讀此 答案

你不需要__main__.py 那是為了當你想從命令行運行python3 -m package (而不是python3 package/module.py或類似的東西)。 看到這個答案

在這種情況下,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.chdirsys.path.append hack。 至少,python unittest 工作不需要它們。
  • 使用文檔中顯示的模式創建單元測試(通過繼承 unittest.TestCase)
  • 運行你的單元測試
python -m unittest

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM