簡體   English   中英

在沒有已知父 package 錯誤的情況下嘗試相對導入

[英]Attempted relative import with no known parent package error

Error: While importing "wsgi-contract-test", an ImportError was raised:

Traceback (most recent call last):
  File "/Users/karl/Development/tral/bin/tral-env/lib/python3.9/site-packages/flask/cli.py", line 236, in locate_app
    __import__(module_name)
  File "/Users/karl/Development/tral/test/contract/inject/wsgi-contract-test.py", line 8, in <module>
    from . import (
ImportError: attempted relative import with no known parent package

ERROR (run-tral): trap on error (rc=2) near line 121
make: *** [component.mk:114: tral-local-run-api-contract-test] Error 2

wsgi-合同-test.py:

from ...libs.tral import app, setup_from_env
from ...libs.tral import routes

我在libs/tral目錄下有常規源文件,但是此測試的入口文件位於test/contract/inject下。 我不想將這個測試文件移動到庫中,因為這個文件應該遠離生產代碼,因為它是一個相當危險的文件安全性。

在 node.js 中,這可以正常工作,但 python 進口似乎有些東西我沒有掌握?

由於測試不屬於src樹,因此基本上有兩種方法。 如果您正在測試一個,您將經常安裝它(在 virtualenv 中),然后以與其他任何地方完全相同的方式導入它。 通常,您還可以通過全新安裝測試來執行此操作:這具有很大的優勢,即您的測試反映了真實的設置,並有助於捕獲諸如忘記提交/包含文件(有罪)之類的錯誤,並且只有在部署后才注意到。 ..

另一種選擇是修改sys.path以便您的測試有效地與您的生產代碼位於同一位置:

# /test/contract/inject.py
from pathlib import Path
import sys

sys.path.insert(0, str(Path(__file__).parent.parent.parent))

由於sys.path使用 strs 您可能更喜歡使用os.path ,就像 SO 上的每個其他示例一樣。 就我個人而言,我沉迷於 pathlib。 這里:

  • __file__是當前文件的絕對路徑
  • Path(str)將其包裝在pathlib.Path object
  • .parent讓你上樹,然后
  • str()轉換回 sys.path 期望的格式,否則它將不起作用。

使用測試運行器

通常我們使用測試運行器進行測試。 但是這些測試需要一個正在運行的實例:沒問題:

# tests/conftest.py
import pytest
from sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))
# now pytest can find the src
from app import get_instance # dummy

@pytest.fixture
def instance():
    instance = get_instance(some_param)
    # maybe
    instance.do_some_setup()
    yield instance
    # maybe
    instance.do_some_cleanup()

如果您不需要進行任何清理,則可以只return實例而不是產生它。 然后在另一個文件(為了整潔)中編寫如下測試:

# tests/test_instance.py

def test_instance(instance): # note how we requested the fixture
    assert instance.some_method()

然后使用 pytest 運行測試:

pytest tests/

Pytest 將運行 conftest.py 中的代碼,在名稱以test開頭的文件中發現所有以 test 開頭的test conftest.py ,運行測試(提供您定義的所有夾具)並報告。

夾具壽命

有時旋轉固定裝置可能很昂貴。 請參閱夾具 scope上的文檔,告訴 pytest 將夾具保持在周圍並將其提供給多個測試。

使用運行器與僅運行腳本

不必使用跑步者。 但它們確實有很多優點:

  • 體面的指標,例如代碼/分支覆蓋率
  • 每個人都使用它們
  • 針對不同環境的並行測試(例如 python 版本)
  • 測試往往更整潔

我理所當然地認為 Python 能夠處理簡單的相對路徑; 不是這樣。 相反,我只是添加了我想要包含在PYTHONPATH變量和 walla 中的包的路徑,它找到了所有內容。

export PYTHONPATH="${PYTHONPATH}:$(pwd)/libs"

然后從根項目目錄運行它。

我不得不將代碼更改為以下內容:

from tral import app, setup_from_env
from tral import routes

暫無
暫無

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

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