pytest 'ImportError : No YadaYadaYada'라는 모듈이없는 PATH 문제


231

easy_install을 사용하여 Mac에 pytest를 설치하고 파일 구조가 다음과 같은 프로젝트에 대한 테스트 작성을 시작했습니다.

repo/
repo/app.py
repo/settings.py
repo/models.py
repo/tests/
repo/tests/test_app.py

py.testrepo 디렉토리에서 실행 하면 모든 것이 예상대로 작동합니다.

그러나 Linux 또는 Windows에서 동일한 것을 시도하면 (둘 다 pytest 2.2.3이 있음) 내 응용 프로그램 경로에서 처음으로 가져 오기 할 때마다 짖습니다. 예를 들어from app import some_def_in_app

이 시스템에서 py.test를 실행하려면 PATH를 편집해야합니까? 누구든지 이것을 경험 했습니까?


4
다음 은 setuptools로 수정하는 방법입니다.
ederag

4
@hoefling 답변을 확인하고 오랜 시간이 지나도 허용되는 경우 허용되는 것을 변경하십시오.
Davide

답변:


91

예, cdtests 디렉토리 로 가면 소스 폴더가 Python의 경로에 없습니다 .

두 가지 선택이 있습니다 :

  1. 테스트 파일에 다음과 같은 경로를 수동으로 추가하십시오.

    import sys, os
    myPath = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, myPath + '/../')
  2. env var로 테스트를 실행하십시오 PYTHONPATH=../.


11
언제 cd디렉토리에 갈까요? 나는 py.test나의 뿌리에서 뛰고있다 . 내가 실수하지 않고 pytest가 내 폴더를 걷는 것처럼 의미하지 않는 한
MattoTodd

그것이 cd문제라면, Mac에서도 치지 않습니까?
MattoTodd

오, 나는 그것을 잘못 읽었고 tests 디렉토리에서 작동하지 않는다고 생각했다. 여전히 제안 1의 트릭이 효과가 있습니다. Linux 만 사용하므로 다른 OS의 동작을 설명 할 수 없습니다.
Not_a_Golfer

모든 test.py 파일에 그런 수입품이 있습니까?
MattoTodd

4
예, 그러나 디렉토리 구조는 일반적으로 약간 다릅니다. 일반적으로 루트 디렉토리 아래에 / src 및 / test를 유지합니다.
Not_a_Golfer

275

py.test가 PYTHONPATH 자체에 현재 디렉토리를 추가하지 않는 이유는 확실하지 않지만 다음은 해결 방법입니다 (저장소 루트에서 실행).

python -m pytest tests/

파이썬이 PYTHONPATH에 현재 디렉토리를 추가하기 때문에 작동합니다.


2
명령을 실행하는 레벨이 아닌 응용 프로그램을 실행하기위한 코드가있는 경우 상대 가져 오기를 절대로 다시 작성해야합니다. 예를 들어 : project/test/all-my-tests그리고 project/src/app.py그 변경 app.py으로 인해 __main__.py파일을 사용 하여 간접적으로 호출해야 호출 project/src을 사용할 수 있습니다 python -m src. 내가 알 수있는 한 지저분한 일들.
Zelphir Kaltstahl

3
@Zelphir : 절대 가져 오기를 사용하는 것이 좋습니다. Habnabit의 모범 사례 포장에 대한 좋은 기사가 있습니다 blog.habnab.it/blog/2013/07/21/python-packages-and-you를 , 그리고 PEP8는 암시 상대 수입은 사용해서는 안됩니다 파이썬에서 삭제되었습니다 "라고 말한다 삼." python.org/dev/peps/pep-0008 참조하십시오 .
Apteryx

1
@Apteryx 당신은 "프로젝트 절대"를 의미합니까? /home/user/dev/projectxyz/src ...대부분의 경우 다른 컴퓨터에서 실행되지 않고 실제로는 좋지 않을 수 있기 때문 입니다. 필자는 모듈이 파일 실행과 동일한 폴더에 있더라도 항상 전체 프로젝트 루트를 모듈 경로에 작성해야한다고 생각합니다. 나는 이것이 최선의 방법으로 간주된다는 것을 몰랐으므로 유용한 정보입니다. 감사합니다. 나는 여전히 완벽하지는 않지만 대부분의 pep8에 동의합니다.
Zelphir Kaltstahl

1
@Zelphir, 그렇습니다. 파이썬에서 절대 수입이라는 용어는 항상 "프로젝트 절대"를 의미한다고 생각합니다. python.org/dev/peps/pep-0328/#rationale-for-absolute-imports를 참조하십시오 . 실제로 최소한 기본 "가져 오기"메커니즘을 사용하여 임의의 절대 경로 위치에서 가져올 수 없습니다.
Apteryx

4
__init__.py테스트를 추가 하여 문제를 해결했습니다. 이제 사용할 수 있습니다pytest
Kiran Kumar Kotari

154

conftest 해결책

최소 침습적 솔루션라는 빈 파일을 추가하고 conftest.py에서 repo/디렉토리를 :

$ touch repo/conftest.py

그게 다야. 맹 글링하기 위해 커스텀 코드를 작성할 필요가 없으며 , sys.path드래그 PYTHONPATH하거나 __init__.py자신이 속해 있지 않은 디렉토리에 배치 해야합니다.

이후 프로젝트 디렉토리 :

repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
     └── test_app.py

설명

pytest에 대한 외모 conftest테스트 컬렉션 모듈은 사용자 정의 후크 및 비품을 수집하고, 그들로부터 사용자 정의 개체를 가져하기 위해하기 pytest의 상위 디렉토리에 추가 conftest.py받는 사람sys.path (이 경우 repo디렉토리).

다른 프로젝트 구조

다른 프로젝트 구조가 conftest.py있는 경우 패키지 루트 디렉토리 (패키지를 포함하지만 패키지 자체는 아니므로)를 포함 하지 않는 루트 디렉토리에 배치하십시오 __init__.py.

repo
├── conftest.py
├── spam
   ├── __init__.py
   ├── bacon.py
   └── egg.py
├── eggs
   ├── __init__.py
   └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

src 나열한 것

이 방법은 함께 사용할 수 있지만 src레이아웃 (장소 conftest.py에서 srcDIR) :

repo
├── src
   ├── conftest.py
   ├── spam
      ├── __init__.py
      ├── bacon.py
      └── egg.py
   └── eggs 
       ├── __init__.py
       └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

추가 것을주의 srcPYTHONPATH완화시킨다 의미와 혜택 src레이아웃을! 설치된 패키지가 아닌 리포지토리에서 코드를 테스트하게됩니다. 당신이 그것을해야한다면, 아마도 srcdir 이 전혀 필요하지 않을 수도 있습니다 .

여기서 갈 곳

물론, conftest모듈은 소스 코드 발견을 돕는 일부 파일이 아닙니다. 여기에서 pytest프레임 워크 의 모든 프로젝트 별 개선 사항 과 테스트 스위트의 사용자 정의가 발생합니다. 문서 전체 pytestconftest흩어져있는 모듈 에 대한 많은 정보가 있습니다 . 로 시작 : 로컬 디렉토리 별 플러그인conftest.py

또한 SO는 conftest모듈 에 대한 훌륭한 질문 이 있습니다 .py.test에서 conftest.py 파일의 사용법은 무엇입니까?


2
@ aaa90210 문제를 재현 할 수는 없지만 (루트 디렉토리의 conftest에서 가져 오기는 모든 수준에서 작동합니다) conftest 파일은 예약 된 이름이므로 가져 오지 않아야합니다 pytest. 그렇게함으로써 미래의 오류를 위해 씨앗을 심습니다. 명명 된 다른 모듈을 작성 utils.py하고 테스트에 재사용 할 코드를 배치하십시오.
hoefling

4
엄지 손가락! 이것은 나를 위해 잘 작동하는 유일한 솔루션입니다.
130

4
반드시 받아 들여야 할 답변이어야합니다-감사합니다!
Martin Peck

2
논리적으로 conftest.py응용 프로그램 코드에 속하지 않으며 imo 아래에 배치하는 src/것이 올바르지 않습니다.
Nik O'Lai

2
이 답변은 SO의 고정 헤더이어야합니다. 많은 감사합니다.
Rigoberta Raviolini

119

나는 같은 문제가 있었다. 빈 __init__.py파일을 tests디렉토리 에 추가하여 수정했습니다 .


77
이는 것을주의 하지 py.test 추천 : avoid “__init__.py” files in your test directories. This way your tests can run easily against an installed version of mypkg, independently from the installed package if it contains the tests or not.SRC : pytest.org/latest/goodpractises.html
K. - 마이클 찬성

24
나는 같은 질문으로 여기에 왔고 __init__.py테스트 디렉토리 에서 제거하면 문제가 해결되는 것을 발견 했습니다.
101

3
@mafro 문제가 표시되지 않습니까? 테스트는 가져 오기 가능한 코드 일 필요는 없습니다. 테스트 실행 프로그램에서 찾을 수 있습니다. 테스트 할 코드 만 테스트 패키지가 아닌 설치된 패키지 / 모듈이어야합니다.
K.-Michael Aye

5
__init__.py하위 디렉토리에 추가하면 test/설치된 하위 모듈에 대해 해당 하위 디렉토리에서 특정 테스트를 실행하기위한 절대 가져 오기 작업이 수행됩니다. 감사.
Bryce Guinta

7
당신은 거기 가서 : doc.pytest.org/en/latest/goodpractices.html은 정말 쉽게 구글로 찾을 수 있습니다.
K.-Michael Aye

46

다음 pytest을 사용하여 모듈로 실행하십시오 . python -m pytest tests


3
이것은 작동하는 솔루션 인 것처럼 보이지만 누구나 왜 설명 할 수 있습니까? python -m pytest"작동하기 때문에"이외의 설명없이 그냥 사용하는 것보다 근본적인 원인을 고치기를 원합니다.
Janne Enberg

4
이것은 프로젝트 계층 구조가 예를 들어 다음 package/src package/tests에서 tests가져올 때 발생합니다 src. 모듈로 실행하면 가져 오기가 실행 위치를 기준으로 한 절대 값으로 간주됩니다.
스테파노 메시나

1
이 솔루션이 도움이되었습니다. 감사합니다! 그 원인은 파이썬 버전의 충돌 때문이었습니다. pytest 테스트는 이전 Python 버전에서 작동합니다. 내 상황에서 내 파이썬 버전은 3.7.1이며 python -m pytest 테스트는 작동하지만 pytest 테스트는 작동하지 않습니다.
Ruxi Zhang

1
에서 Pytest "파이썬 -m pytest [...] 대신 pytest의 [...] 수율 전 전화가 sys.path에 현재 디렉토리를 추가 것을 제외하고는 거의 상응하는 행동.와 pytest 실행"
Moad Ennagi

37

프로젝트 루트에서 PYTHONPATH로 실행할 수 있습니다.

PYTHONPATH=. py.test

또는 편집 가능한 가져 오기로 pip install을 사용하십시오.

pip install -e .   # install package using setup.py in editable mode

3
그건 나를 위해 작동하지 않았다 test가 아닌 디렉토리 src디렉토리 구조와 모두 들어있는 디렉토리에서 전화 testsrc디렉토리를.
Zelphir Kaltstahl 2018 년

21

나는 이것을 당신의 질문과 내 자신의 혼란에 대한 답변으로 만들었습니다. 도움이 되길 바랍니다. py.test 명령 행과 tox.ini에서 PYTHONPATH에주의하십시오.

https://github.com/jeffmacdonald/pytest_test

구체적으로, py.test와 tox에 포함하고있는 모듈을 찾을 위치를 알려줘야합니다.

py.test를 사용하면 다음을 수행 할 수 있습니다.

PYTHONPATH=. py.test

tox와 함께 tox.ini에 추가하십시오 :

[testenv]
deps= -r{toxinidir}/requirements.txt
commands=py.test
setenv =
    PYTHONPATH = {toxinidir}

1
연결 한 프로젝트에 대해 간단히 설명해 주시겠습니까?
JF Meier

1
어쩌면 그저 나이지만 프로젝트의 README는 매우 상세하며 stackoverflow에 대한 나의 의견은 왜 repo를 만들 었는지 말합니다.
Jeff MacDonald

5
꼭 필요한 것은 아니지만, 답변 자체에 답변의 주요 내용을 포함시키는 것이 일반적인 정책입니다. 왜냐하면 링크 된 리소스가 오래 사라 졌을 때부터 지금부터 x 년 내에 답변을 이해할 수있게하기 때문입니다.
JF Meier

:) 오 잘. 그게 인터넷입니다.
Jeff MacDonald

9

Flask에서도 같은 문제가있었습니다.

내가 추가했을 때 :

__init__.py

폴더를 테스트하기 위해 문제가 사라졌습니다 :)

응용 프로그램에서 폴더 테스트를 모듈로 인식하지 못할 수 있습니다.


8

__init__.py소스의 상위 폴더에서 최상위를 제거하여 문제를 해결했습니다 .


1
나를 위해 고쳤다. 누군가 이것을 설명 할 수 있습니까?
aboger

바로 여기이 문제도 해결되었습니다. 누군가가 그것을 가지고 있다면 분명히 이것에 대한 설명을보고
싶습니다

나는 init .py를 추가 했지만 여전히 같은 문제에 직면했지만이 솔루션은 나에게도 효과가 있었다.
Abhijit

7

ConftestImportFailure: ImportError('No module named ...실수로 __init__.pysrc 디렉토리 에 파일을 추가했을 때 이상한 오류가 발생 하기 시작했습니다 (파이썬 패키지가 아니고 모든 소스의 컨테이너 일뿐입니다).


3

더 간단한 것으로 인해이 오류가 발생했습니다 (사소한 말조차 할 수 있음). pytest모듈을 설치하지 않았습니다 . 그래서 간단하게 apt install python-pytest나를 위해 고쳤습니다.

'pytest'는 setup.py에 테스트 종속성으로 나열되었을 것입니다. 테스트 요구 사항도 설치하십시오.


3

나는 비슷한 문제가 있었다. pytest내가 일하고있는 환경에 설치된 모듈을 인식하지 못했습니다.

pytest동일한 환경에 설치 하여 문제를 해결했습니다 .


venv 내부에서 pytest를 사용하고 있었지만 전 세계에 설치 하여이 오류를 발생 시켰습니다. 글로벌 버전을 제거하고 venv 내부에 설치 한 후 작동했습니다.
Markus Ressel

2

나를 위해 tests.pyDjango가 tests디렉토리 와 함께 문제를 생성했습니다 . 제거하면 tests.py문제가 해결되었습니다.


2

상대적 가져 오기를 잘못 사용 하여이 오류가 발생했습니다. OP 예제에서 test_app.py는 다음을 사용하여 함수를 가져와야합니다.

from repo.app import *

그러나 자유롭게 __init__.py 파일은 파일 구조 주위에 흩어져 있지만 작동 하지 않으며 파일과 테스트 파일이 동일한 디렉토리에 있지 않으면 일종의 ImportError를 만듭니다.

from app import *

다음은 내 프로젝트 중 하나와 관련이있는 예입니다.

내 프로젝트 구조는 다음과 같습니다.

microbit/
microbit/activity_indicator/activity_indicator.py
microbit/tests/test_activity_indicator.py

test_activity_indicator.py에서 activity_indicator.py에 액세스하려면 다음이 필요했습니다.

  • 올바른 상대 가져 오기로 test_activity_indicatory.py를 시작하십시오.
    from microbit.activity_indicator.activity_indicator import *
  • 프로젝트 구조 전체에 __init__.py 파일을 넣습니다.
    microbit/
    microbit/__init__.py
    microbit/activity_indicator/__init__.py
    microbit/activity_indicator/activity_indicator.py
    microbit/tests/__init__.py
    microbit/tests/test_activity_indicator.py

0

모듈을 가져올 수 없기 때문에 테스트가 중단되는 경우가 많았습니다. 연구 후 시스템이 잘못된 위치에서 파일을보고 있음을 발견했으며 모듈을 포함한 파일을 복사하여 문제를 쉽게 극복 할 수있었습니다. 올바르게 가져 오기 위해 명시된 것과 동일한 폴더. 또 다른 솔루션 제안은 가져 오기 선언을 변경하고 MutPy에 올바른 유닛 경로를 표시하는 것입니다. 그러나 여러 장치가 이러한 종속성을 가질 수 있으므로 선언에서도 변경 사항을 커밋해야하므로 장치를 폴더로 옮기는 것이 좋습니다.


OP의 질문을 제공하는 다른 답변이 있으며 얼마 전에 게시되었습니다. 답변을 게시 할 때는 특히 오래된 질문에 답변 할 때 새 솔루션을 추가하거나 실질적으로 더 나은 설명을 추가하십시오. 때로는 특정 답변에 대한 의견을 게시하는 것이 좋습니다.
help-info.de

@ help-info.de에서 주석에 추가로 : 여기에 대답 질문에 대한 가이드에 대한 링크입니다 stackoverflow.com/help/how-to-answer
NOD의 손

0

Dirk Avery의 Medium 게시물 (개인 경험에서 지원)에 따르면 프로젝트에 가상 환경을 사용하는 경우 시스템 전체에 pytest를 설치할 수 없습니다. 가상 환경에 설치하고 해당 설치를 사용해야합니다.

특히 두 위치에 pytest설치 한 경우 시스템 설치를 사용하므로 명령을 실행하면 작동하지 않습니다. 다른 답변에서 설명했듯이 간단한 솔루션 하나 python -m pytest대신 pytest; 이것은 환경 버전의 pytest를 사용하기 때문에 작동합니다. 또는 시스템의 pytest 버전을 제거 할 수도 있습니다. 가상 환경을 재 활성화 한 후 pytest명령이 작동해야합니다.


지금까지 나를 위해 일한 유일한 것은였습니다 python -m pytest tests/.
Nik O'Lai

0

Flask 튜토리얼을 따라갈 때도 같은 문제가 발생했으며 공식 Pytest 문서 에서 답을 찾았습니다 .

setup.py최소한 다음 두 줄 을 사용 하여 프로젝트의 루트 디렉토리에 파일 을 작성해야 합니다.

from setuptools import setup, find_packages
setup(name="PACKAGENAME", packages=find_packages())

여기서 PACKAGENAME은 앱 이름입니다. 그런 다음 pip로 설치해야합니다.

pip install -e .

-e플래그는 pip에게 패키지를 편집 가능 또는 "개발"모드로 통합하도록 지시합니다. 따라서 다음에 실행할 pytest때는 표준에서 앱을 찾아야합니다 PYTHONPATH.


0

내 해결책 :

다음을 포함 conftest.py하는 test디렉토리에 파일을 작성하십시오 .

import os
import sys
sys.path.insert(0,os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/code/")

이것은 모든 테스트 파일을 수정 하거나, env 변수를 설정하거나 절대 / 상대 경로를 엉망으로 만들지 않고 파이썬 경로에 관심있는 폴더를 추가합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.