pytestはモジュールをインポートできませんが、Pythonはインポートできます


113

Pythonでパッケージを作成しています。私はvirtualenvを使用しています。私はvirtualenvの.pthパスでモジュールのルートへのパスを設定します。これにより、コードの開発およびテスト中にパッケージのモジュールをインポートできるようになります(質問1:これは良い方法ですか?)。これはうまくいきます(ここに例があります、これは私が望む動作です):

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python
Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from rc import ns
>>> exit()
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python tests/test_ns.py 
issued command: echo hello
command output: hello

ただし、PyTestを使用しようとすると、いくつかのインポートエラーメッセージが表示されます。

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ pytest
=========================================== test session starts ============================================
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/zz/Desktop/GitFolders/rc, inifile: 
collected 0 items / 1 errors 

================================================== ERRORS ==================================================
________________________________ ERROR collecting tests/test_ns.py ________________________________
ImportError while importing test module '/home/zz/Desktop/GitFolders/rc/tests/test_ns.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ns.py:2: in <module>
    from rc import ns
E   ImportError: cannot import name ns
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================= 1 error in 0.09 seconds ==========================================
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ which pytest
/home/zz/Desktop/VirtualEnvs/VEnvTestRc/bin/pytest

私は少し困惑しています、これはインポートエラーを示しているように見えますが、Pythonは問題なく動作するので、なぜPyTestに特に問題があるのですか?理由/改善策についての提案(質問2)?PyTestの「ImportError:cannot import」エラーをググってスタックオーバーフローしましたが、私が得たヒットは、不足しているpythonパスとこれに対する解決策に関連していましたが、ここでは問題のようではありません。助言がありますか?

回答:


117

答えが見つかりました:

__init__.pypytestを使用する予定がある場合は、TESTSを含むフォルダにファイルを置かないでください。私はそのようなファイルを1つ持っていて、それを削除すると問題が解決しました。

これは実際にはpytestのPATH問題の 2番目の回答へのコメントに埋め込まれていました'ImportError:Noadaという名前のモジュールはありませんでした。


44
おかしい。私は同じ問題を持っていたと私は追加する必要がありましたinitは私のテストフォルダにの.py。
Ev。

5
ええ、これは(あなたのケースにあったとしても)一般的な解決策ではありません。なぜこれを読むべきかを理解するためです:docs.pytest.org/en/latest/goodpractices.html#test-package-name
juan

1
この情報は誤っており、誤解を招く可能性があります。テストフォルダーにinit .pyを追加した後、すべてが正常に機能しました
レオナルドオスタン

1
@LeonardoOstanそれはあなたにとって間違っているかもしれませんが、それはこの情報が一般的に間違っているという意味ではありません。私の場合、それは問題を解決しました。
Desprit

77

なぜこれが機能するのか理解できませんが、同じ問題があり、実行するとテストは正常に機能しますpython -m pytest

私はvirtualenvにいて、pytestもグローバルに利用できます:

(proj)tom@neon ~/dev/proj$ type -a python
python is /home/tom/.virtualenvs/proj/bin/python
python is /usr/bin/python

(proj)tom@neon ~/dev/proj$ python -V
Python 3.5.2

(proj)tom@neon ~/dev/proj$ type -a pytest
pytest is /home/tom/.virtualenvs/proj/bin/pytest
pytest is /usr/bin/pytest

(proj)tom@neon ~/dev/proj$ pytest --version
This is pytest version 3.5.0, imported from /home/tom/.virtualenvs/proj/lib/python3.5/site-packages/pytest.py

1
私にとっても仕事をしました、それは、あなたのv.envの代わりに定義されたpythonバージョンによって実行されるということです。
Nebulosar

11
理由の1つは、python -m pytest [...]「現在のディレクトリもに追加される」ことsys.pathです。
minusf

Windows 10でも同じで、python -m pytestを実行すると解決しました
Duccio

これは私が実行しなければならなかった私の仮想環境内のほかのために働いていたpython3 -m pytest
リシラジ

PYTHONPATH=.:./src pytestmakeターゲットとして使用している@minusfのコメントに基づいています。
jan groth

29

私はプロジェクトルートの__init__.pyを削除してこれを解決しました:

.
├── __init__.py <--- removed
├── models
   ├── __init__.py
   ├── address.py
   ├── appointment.py
   └── client.py
├── requirements.txt
├── setup.cfg
├── tests
   ├── __init__.py
   ├── models
      ├── __init__.py
      ├── appointment_test.py
      └── client_test.py
   └── other_test.py
└── script.py

4
受け入れられた答え__init__.py file in a folder containing TESTSは私の問題を解決しませんでした。これはうまくいきました。ファイルの階層が原因だと思います。
smido

__init__.pyファイルを削除しました。私はまだ問題に直面していました。conftest.pyファイルをルートディレクトリに追加するとうまくいきました。
Vijay Sali

conftest.pyはルートではなく/ testsにあると思います
アーロン

conftest.pyファイルをルートディレクトリに取得すると、修正されました。テストディレクトリにinit .pyファイルがないこと
更新

2
この解決策は私にとってはうまくいきましたが、これがインポートエラーを引き起こすことを誰かが知っていますか?
Aldo Okware

19

私は同じ問題を抱えていましたが、言及されたものとは別の理由で:

パッケージが仮想環境にインストールされている間、私はpy.testをグローバルにインストールしました。

解決策はpytest、仮想環境にインストールすることでした。(シェルがBashと同様に実行可能ファイルをハッシュする場合は、を使用するhash -rか、への完全パスを使用しますpy.test


2
アナコンダを使用して、私が同じ卑劣な問題を抱えていることに気づきました。でpytest作成したvirtualenv を追加するのを忘れてcondaいましpytestたが、anacondaのルート環境で使用できます。したがって、pytest 見つかりましたが、環境にインストールされているパッケージは見つかりませんでした。
Overdrivr

1
同じ問題がありました。pytestはvirtualenvではなくグローバルにインストールされました。pip3 install pytestvirtualenv内で問題が修正されました。
Ankit Singh 2018

7

この問題は、tests.pyファイルとを含むテストフォルダがある場合に発生しますtests/__init__.py

収集中にpytestはフォルダーを検出しますが、フォルダーからテストファイルをインポートしようとすると、tests.pyファイルによってインポートの問題が発生します。

修正するには、単にtests.pyファイルを削除し、すべてのテストをtests/フォルダー内に配置します。

特定のケースでは、修正は正確に次のようになります。

  • ファイルを削除します /home/zz/Desktop/GitFolders/rc/tests.py
  • /home/zz/Desktop/GitFolders/rc/tests/__init__.py存在することを確認してください

4

私は同様の問題、まったく同じエラーがありましたが、原因は異なりました。私はテストコードを問題なく実行していましたが、古いバージョンのモジュールに対してです。前のバージョンのコードでは、1つのクラスが存在しましたが、他のクラスは存在しませんでした。コードを更新したら、次のコードを実行してインストールする必要がありました。

sudo pip install ./ --upgrade

更新されたモジュールをインストールすると、pytestを実行すると正しい結果が生成されました(正しいコードベースを使用していたため)。


1
これは私のために働いた!私のモジュールは同時に、pytestの実行に使用していたDockerコンテナーにライブラリーとしてインストールされました。pythonインタープリターを実行すると、更新されたコードが検出されますが、pytestはライブラリが最初にインストールされたときと同じようにコードを検出し続けます。実行するとpip install ./ --upgrade、インストールされているlibのバージョンが最新のコードで更新され、pytestがこの最新バージョンも検索できるようになりました。
FaustoW

4

私の場合、パッケージが同じ名前の別のパッケージ/ディレクトリを指し、そのパスが実際に必要なフォルダーの1つ上のレベルにあるため、インポートエラーが発生しました。これは、一部の人々が_ init _.py を削除する必要がある一方で、他の人々が追加し直す必要がある理由も説明していると思います。

違いを比較するために、コンソールとスクリプトの両方にprint(the_root_package.__path__)(の後にimport the_root_package)入れましたpythonpytest

BOTTOM LINE:実行するpythonと、インポートしたパッケージは、実行しpytestたときのパッケージと異なる場合があります。


3

パッケージを仮想環境にインストールします。
次に、新しいシェルを起動し、仮想環境を再度ソースします。


1
それは私の問題だった:新鮮なvenvリロードせずにインストールします
フリーズ

2

上記の答えは私にはうまくいきません。(テストモジュール)のsys.path上部に見つからないモジュールの絶対パスを追加することで解決しましたtest_xxx.py

import sys
sys.path.append('path')

1
これらの行をの最上部test_main.pyに配置する代わりconftest.pyに、テストディレクトリに配置すると、うまくいきました。ファイルくずの代わりに、プログラムによる解決策を提供してくれてありがとう。
キャメロンハドソン

2

もともとpython 2.7で開発され、現在python 3.xに移行されたpythonコードに関連している場合、問題はおそらくインポートの問題に関連しています。

たとえばbase、同じディレクトリにあるファイルからオブジェクトをインポートする場合、これはpython 2.xで機能します。

from base import MyClass

python 3.xでは、baseフルパスに置き換える必要.base があります。そうしないと、上記の問題が発生します。だから試してください:

from .base import MyClass

2

今日、この問題が発生しておりpython -m pytest、プロジェクトディレクトリのルートから呼び出すことで解決しました。

pytest同じ場所からの通話でも問題が発生しました。

私のプロジェクトディレクトリは次のように構成されています。

api/
 - server/
  - tests/
      - test_routes.py
  - routes/
      - routes.py
 - app.py

モジュールroutesは私のtest_routes.pyようにインポートされました:from server.routes.routes import Routes

お役に立てば幸いです。


リマインダーをありがとう、私は過去にそのトリックを使わなければならなかった、そしてそれはpytestのドキュメントにある。
Jason R Stevens CFA

1

別の特別なケース:

toxの使用に問題がありました。そのため、私のプログラムは問題なく実行されましたが、toxを使用した単体テストでは不満が続いていました。(プログラムに必要な)パッケージをインストールした後、tox.iniのユニットテストで使用されるパッケージを追加で指定する必要があります

[testenv]
deps =
    package1
    package2 
...

1

VSCodeを使用してこれを取得していました。コンダ環境があります。VScodeのPython拡張機能で、自分が行った更新を確認できないと思います。

python c:\Users\brig\.vscode\extensions\ms-python.python-2019.9.34911\pythonFiles\testing_tools\run_adapter.py discover pytest -- -s --cache-clear test
Test Discovery failed:

私は走らなければなりませんでした pip install ./ --upgrade


それピップコマンドはエラーを返します:Directory './' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.
デレク

1

conftest.pyを編集して、次のコード行を追加します。

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(file), '..')))

そして、ターミナルを通じてテストケースを実行しようとする場合、次の例を使用してください:

python -m pytest test_some_step_file_steps.py --html=HTML_step_file_output.html --self-contained-html

NameError: name 'file' is not defined-ファイルは何に等しいべきですか?
Koshmaar

1

Pythonのインポートシステムにとってさらに大きな勝利。コンセンサスがない理由は、機能するものはおそらく環境とその上で使用しているツールに依存するためだと思います。

私はこれをVS Codeのconda環境のWindowsのテストエクスプローラー、Python 3.8で使用しています。

私が働かなければならない設定は:

mypkg/
    __init__.py
    app.py
    view.py
tests/
    test_app.py
    test_view.py

この設定では、インテリセンスが機能し、テスト検出も機能します。

ここで推奨されているように、私はもともと以下を試したことに注意してください

src/
    mypkg/
        __init__.py
        app.py
        view.py
tests/
    test_app.py
    test_view.py

srcフォルダーがインポートシステムの精神を吹き飛ばしただけなので、VS Codeからこれを機能させる方法を見つけることができませんでした。これをコマンドラインから機能させる方法があると想像できます。Pythonプログラミングへの比較的新しい変換として、COMで作業するという懐かしい感じがしますが、少し面白くありません。


1

これに関する私の2セント:仮想環境を使用していない場合、pytestは偶然に失敗します。うまくいくこともあれば、うまくいかないこともあります。

したがって、解決策は次のとおりです。

  • pip uninstallでpytestを削除する
  • あなたのvenvを作成する
  • venvをアクティブ化する
  • プロジェクトパスを編集可能モードでpipインストールして、pytestによってモジュールとして扱われるようにします(それ以外の場合、pytestは内部インポートを検出しません)。そのためのsetup.pyファイルが必要になります
  • pytestを含むパッケージをインストールする
  • 最後に、テストを実行します

Windows PowerShellを使用したコード:

pip uninstall pytest
python.exe -m venv my_env
.\my_env\Scripts\activate
(my_env) pip install -e .
(my_env) pip install pytest pytest-html pandas numpy

そして最後に

(my_env) pytest --html="my_testing_report.html"

setup.pyの例、pip install -eの場合:

import setuptools

setuptools.setup(
    name='my_package',
    version='devel',
    author='erickfis',
    author_email='erickfis@gmail.com',
    description='My package',
    long_description='My gooood package',
    packages=setuptools.find_packages(),
    classifiers=[
        'Programming Language :: Python :: 3',
        'Operating System :: OS Independent',
    ],
    include_package_data=True
)

1

私はあなたがどんな__init__.pyファイルも削除しなければならないと言っている投稿に同意しません。代わりに行う必要があるのは、を変更することsys.pathです。

sys.path通常のコード実行時に印刷する実験を実行します。次にsys.path、pytestを介してコードを実行しながら印刷します。これらの2つのパスに違いがあることに気づくと思います。そのためにpytestが機能しなくなります。

これを修正するには、最初の実験からのパスを2番目の0番目のインデックスに挿入します。

みましょう'/usr/exampleUser/Documents/foo'の最初の要素であるprint(sys.path)実験1について。

以下は、問題を修正するコードです。

import sys sys.path[0] = '/usr/exampleUser/Documents/foo'

これをファイルの先頭、実際のインポート文の前に置きます。

出典:私はこれを自分で処理しており、上記のプロセスで解決しました。


1

すべてを同じに保ち、ルートフォルダーに空のテストファイルを追加しただけです。解決しました

調査結果は次のとおりです。この問題はしばらくの間私を悩ませました。私のフォルダ構造は

mathapp/
    - server.py  
    - configuration.py 
    - __init__.py 
    - static/ 
       - home.html  
tests/            
    - functional 
       - test_errors.py 
    - unit  
       - test_add.py

pytestはModuleNotFoundErrorで不満を示し、ヒントを表示します-テストモジュール/パッケージに有効なPython名があることを確認してください。

mathsappおよびtestsディレクトリと同じレベルのモックテストファイルを導入しました。ファイルには何も含まれていません。今pytestは文句を言わない。

ファイルなしの結果

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 1 item / 1 error

=================================== ERRORS ====================================
_______________ ERROR collecting tests/functional/test_func.py ________________
ImportError while importing test module 'C:\mainak\workspace\0github\python-rest-app-cont\tests\functional\test_func.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests\functional\test_func.py:4: in <module>
    from mathapp.service import sum
E   ModuleNotFoundError: No module named 'mathapp'
=========================== short test summary info ===========================
ERROR tests/functional/test_func.py
!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
============================== 1 error in 0.24s ===============================

ファイルの結果

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 2 items

tests\functional\test_func.py .                                          [ 50%]
tests\unit\test_unit.py .                                                [100%]

============================== 2 passed in 0.11s ==============================

これは私を形作ったトリックです
Subrata Fouzdar

これはこの問題で長い間私にとってうまくいきました。pytestがプロジェクトルートを最初のテストファイルが見つかった場所として扱っているようです。確かにこれはバグですか?
oooyaya

1

PYTHONPATH私がテストを実行している特定の構成に環境変数を設定することで問題を解決しました。

PyCharmでテストファイルを表示している間:

  1. Ctrl+ Shift+A
  2. タイプ Edit Configurations
  3. PYTHONPATH[環境]> [環境変数]を設定します。

1

conftest.pyを検出すると、sys.pathを変更してモジュールからコンテンツをインポートできるconftest.pyため、プロジェクトのルートディレクトリに空のファイルを置くだけです。一般的なディレクトリ構造は次のとおりです。pytestconftest

Root
├── conftest.py
├── module1
   ├── __init__.py
   └── sample.py
└── tests
    └── test_sample.py


0

Pythonが(パスの問題が原因である可能性が高い)の間に、PytestがパッケージをPythonモジュールとして読み取っていない可能性があります。pytestスクリプトのディレクトリを変更するか、モジュールをPYTHONPATHに明示的に追加してみてください。

または、マシンに2つのバージョンのPythonがインストールされている可能性があります。Pythonソースのpytestと実行しているpythonシェルを確認してください。それらが異なる場合(つまり、Python 2と3)、を使用source activateして、モジュールがインストールされているのと同じpythonに対してインストールされているpytestを実行していることを確認します。


0

すべてを試してもエラーが発生する場合は、回避策を講じます。

pytestがインストールされているフォルダーでpytest-envフォルダーに移動します。

pyvenv.cfgファイルを開き ます。

ファイルのinclude-system-site-packagesfalseからtrueに変更します

home = /usr/bin
include-system-site-packages = true
version = 3.6.6

うまくいくことを願っています。投票することを忘れないでください。


0

すでに.pycファイルがある場合は、それらを削除してみてください。

今日、私はこの問題に遭遇しました、これが起こったことです:

最初にMacでpytestを実行し(これによりpycファイルが生成されます)、プロジェクトディレクトリがマウントされた状態でDockerコンテナー(OSは高山)を起動します。次にコンテナーでpytestを実行しようとすると、ImportErrorが発生します。すべてのpycファイルをクリーニングした後、エラーは発生しなくなりました。

これがお役に立てば幸いです。


0

フォルダーにinit .pyファイルが必要な場合は、フォルダーのコピーを作成し、その中のinit .py を削除して、ローカルプロジェクトで機能するテストを実行します。テストを定期的に実行する必要がある場合は、init .pyを別のファイルに移動できるかどうかを確認してください。


0

[解決済み]削除/追加のソリューションに直接ジャンプする前__init__.pyに、クラスでインポートがどのように行われるかを確認することもできます。実際、私は__init__.pyそれが問題であるかもしれないと考えて遊んでいた1日を失いました:)しかし、それは非常に有益でした。

私の場合、あるPythonクラスから別のPythonクラスにクラスを呼び出す方法が間違っていたため、スローされていましたImportError。クラス/モジュールが呼び出される方法を修正し、それが魅力のように機能しました。これが他の人にも役立つことを願っています。

そして、はい、同様のエラーの場合、コードの記述方法に応じて異なる解決策が考えられます。自己デバッグにより多くの時間を費やす方がよい。教訓:)ハッピーコーディング!


1
間違った方法と正しい方法の例をいくつか挙げていただけますか?
Lurifaxel

0

私の場合、私はコンテナーで作業しており、残念ながらpytestは、選択したpython3インタープリターではなくpython2.7を使用する傾向があります。

私の場合、これはうまくいきました:

python3 -m pytest

私のフォルダ構造

/
app/
-module1.py
-module2.py
-tests/
--test_module1.py
--test_module2.py
requirements.txt
README.md

-1

すべてのテストをテストフォルダーに配置したところ、同じエラーが発生しました。私はそのようにそのフォルダにinit .pyを追加することでこれを解決しました:

.
|-- Pipfile
|-- Pipfile.lock
|-- README.md
|-- api
|-- app.py
|-- config.py
|-- migrations
|-- pull_request_template.md
|-- settings.py
`-- tests
    |-- __init__.py <------
    |-- conftest.py
    `-- test_sample.py
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.