web-dev-qa-db-ja.com

Pythonのunittestを使用した相対インポート

Pythonユニットテストと相対インポートを使用しようとしていますが、それを理解できていないようです。関連する質問がたくさんあることは知っていますが、これまでのところどれも役に立ちませんでした。これが繰り返しである場合は申し訳ありませんが、私は本当に助けていただければ幸いですPEP 328の構文を使用しようとしていました http://www.python.org/dev/peps/pep-0328/ しかし私は何か間違っているに違いない。

私のディレクトリ構造は:

project/
    __init__.py
    main_program.py
    lib/
        __init__.py
        lib_a
        lib_b
    tests/
        __init__.py
        test_a
        test_b

私はテストを以下を使用して実行します:

python -m unittest test_module1 test_module2

test_aはlib/lib_aとmain_programの両方をインポートする必要があります。これは、インポートに使用しようとしているtest_aのコードです。

from ..lib import lib_a as lib
from ...project import main_program

どちらもこのエラーを発生させます:

ValueError: Attempted relative import in non-package

すべてのinit。pyファイルは現在空です。

具体的なアドバイスは大歓迎です!!

編集:

これが答えかもしれません: Python Packages? これが機能するかどうかまだ確認しています。

編集II:

明確にするために、この時点で3つの異なる方法でテストファイルを実行しようとしました。

project/tests $ python -m unittest test_a
project/tests $ python -m test_a
project/tests $ ./test_a

3つとも、上記と同じエラーで失敗します。プロジェクトディレクトリで同じ3つの構文を使用すると、次のエラーが発生します。

ValueError: Attempted relative import beyond toplevel package

再度、感謝します。

35
J Jones

私の経験では、次のようにプロジェクトルートがパッケージではない場合が最も簡単です。

project/
  test.py
  run.py
  package/
    __init__.py
    main_program.py
    lib/
      __init__.py
      lib_a
      lib_b
    tests/
      __init__.py
      test_a
      test_b

ただし、python 3.2以降では、unittestモジュールは-tオプションを提供します。これにより、最上位ディレクトリを設定できるため、(package/から)実行できます。

python -m unittest discover -t ..

詳細は nittest docs をご覧ください。

19
kai

私は同じ問題で走っていて、カイの答えがそれを解決しました。私は彼の答えをtest.py(@ gsantaが尋ねたように)の内容で補足したいだけです。 Python 2.7:

from packages.tests import test_a, test_b
import unittest

# for test_a
unittest.main(test_a)

# for test_b
unittest.main(test_a)

その後、あなたはちょうどできます

../project $ python test.py
2

testsおよびpackageが兄弟レベルにあるレイアウトでは:

/project
   /tests
   /package

1つの方法は、packagedir内で開始することです。-sを使用して、testsでのみ検出します。 -tを使用してトップレベルを設定します。

../package $ python3 -m unittest discover -s ../tests -t ..

0
Eric Jarvi