pytest modülü içe aktaramazken python yapabilir


115

Python'da bir paket üzerinde çalışıyorum. Virtualenv kullanıyorum. Modülün köküne giden yolu virtualenv'imde bir .pth yolunda ayarlıyorum, böylece kodu geliştirirken paketin modüllerini içe aktarabilir ve testler yapabilirim (Soru 1: Yapmanın iyi bir yolu mu?). Bu iyi çalışıyor (işte bir örnek, istediğim davranış bu):

(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

Ancak, PyTest'i kullanmayı denersem, bazı içe aktarma hata mesajları alıyorum:

(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

Biraz kafam karıştı, bu bir içe aktarma hatası gösteriyor gibi görünüyor, ancak Python bunu iyi yapıyor, öyleyse neden özellikle PyTest ile ilgili bir sorun var? Nedeni / çözümü için herhangi bir öneri (Soru 2)? PyTest için 'ImportError: içe aktarılamıyor' hatasını googledim ve yığınla aştım, ancak aldığım isabetler eksik python yolu ve bunun çaresi ile ilgiliydi, ki bu buradaki sorun gibi görünmüyor. Baska öneri?

Yanıtlar:


118

Cevabı buldum:

DO NOT a koymak __init__.pysen pytest kullanmayı planlıyorsanız TESTLERİ içeren bir klasöre. Böyle bir dosyam vardı, onu silmek sorunu çözdü.

Bu aslında pytest 'ImportError: YadaYadaYada adlı modül yok' ile PATH sorununun ikinci cevabının yorumlarına gömüldü, bu yüzden görmedim, umarım burada daha fazla görünürlük kazanır.


45
Komik. Aynı sorunu yaşadım ve testler klasörüme init .py eklemem gerekiyordu .
Ev.

5
Evet, bu genel bir çözüm değil (sizin durumunuzda olmasına rağmen), bunun neden okunması gerektiğini anlamak için: docs.pytest.org/en/latest/goodpractices.html#test-package-name
juan

1
Bu bilgi YANLIŞ ve yanıltıcıdır! Ekledikten sonra init testi klasör her şeyi içine .py cezası çalıştı
Leonardo Ostan

1
@LeonardoOstan sizin için yanlış olabilir, ancak bu bilgilerin genel olarak yanlış olduğu anlamına gelmez. Benim durumumda sorunu çözdü.
Desprit

80

Bunun neden işe yaradığını anladığımı söyleyemem ama aynı sorunu yaşadım ve çalıştırırsam testler iyi çalışıyor python -m pytest.

Bir virtualenv içindeyim, pytest dünya çapında da mevcuttur:

(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
Ayrıca işi benim için yaptım, mesele şu ki, sizin v.env'iniz yerine tanımlanan python sürümü tarafından çalıştırılıyor.
Nebulosar

12
bunun bir nedeni python -m pytest [...]"geçerli dizini de ekleyeceği" olabilir sys.path.
eksi

Windows 10'da da aynısı vardı ve python -m pytest çalıştırmak sorunu çözdü
Duccio

Bu, çalıştırmam gereken sanal python3 -m pytest
ortamımda da

@Minusf tarafından yapılan yoruma göre PYTHONPATH=.:./src pytest, bir yapma hedefi olarak kullanıyorum .
Ocak

29

Bunu proje kökümdeki __init__.py'yi kaldırarak çözdüm:

.
├── __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
Kabul edilen cevap __init__.py file in a folder containing TESTSsorunumu çözmedi. Bu çalıştı. Sanırım dosya hiyerarşisi yüzünden.
smido

__init__.pyDosyayı kaldırdım . Hala sorunla karşı karşıyaydım. Conftest.py dosyasını kök dizine eklemek benim için çalıştı.
Vijay Sali

Conftest.py'nin kökte olmamasını / test
etmesini beklerdim

Conftest.py dosyasını kök dizine almak da benim için sorunu çözdü. Testler dizininde bir init .py dosyası yok
güncelleyin

2
Bu çözüm benim için çalıştı, ancak bunun bir içe aktarma hatasına neden olacağını bilen var mı?
Aldo Okware

19

Aynı sorunu yaşadım ama belirtilenlerden başka bir sebepten:

Paketler sanal bir ortama kurulurken, py.test'i global olarak kurdum.

Çözüm, pytestsanal ortama kurmaktı. (Bash'in yaptığı gibi, kabuğunuzun yürütülebilir dosyalarını karma haline getirme durumunda hash -r, tam yolu kullanın veya kullanın py.test)


2
Anaconda kullanarak aynı sinsi sorunu yaşadığımı fark ettim. pytestTarafından oluşturulan virtualenv'i eklemeyi unuttum conda, ancak pytestanaconda'nın kök ortamında mevcut. Bu nedenle pytest olabilir ortamında yüklü herhangi bir paket bulundu, ancak edilmeyecektir.
Overdrivr

1
Ben de aynı sorunu yaşadım. pytest virtualenv'de değil global olarak kuruldu. pip3 install pytestvirtualenv içinde sorunu düzeltti.
Ankit Singh

7

Bu sorun, bir tests.pydosyanız ve tests/__init__.py.

Koleksiyon sırasında pytest klasörü bulur, ancak test dosyalarını klasörden içe aktarmaya çalıştığında, tests.pydosya içe aktarma sorununa neden olur.

Düzeltmek için tests.pydosyayı kaldırın ve tüm testlerinizi tests/klasörün içine koyun .

Özel durumunuz için düzeltme tam olarak:

  • Dosyayı kaldırın /home/zz/Desktop/GitFolders/rc/tests.py
  • /home/zz/Desktop/GitFolders/rc/tests/__init__.pyMevcut olduğundan emin ol

4

Benzer bir sorun yaşadım, tamamen aynı hata, ancak farklı neden. Test kodunu gayet iyi çalıştırıyordum, ancak modülün eski bir sürümüne karşı. Kodumun önceki sürümünde bir sınıf varken diğeri yoktu. Kodumu güncelledikten sonra, yüklemek için aşağıdakileri çalıştırmalıydım.

sudo pip install ./ --upgrade

Pytest'i çalıştıran güncellenmiş modülü kurduktan sonra doğru sonuçlar elde edildi (çünkü doğru kod tabanını kullanıyordum).


1
Bu benim için çalıştı! Modülüm aynı zamanda pytest'i çalıştırmak için kullandığım docker konteynerinde bir kitaplık olarak kuruldu. Python yorumlayıcısını çalıştırırken güncellenmiş kodu bulurdu, ancak pytest kodu kitaplık ilk kurulduğunda olduğu gibi bulmaya devam ederdi. Çalıştırmak pip install ./ --upgrade, lib'nin yüklü sürümünü en son kodla güncelledi ve pytest'in de bu son sürümü bulmasını sağladı.
FaustoW

4

Paketleri sanal ortamınıza kurun.
Ardından yeni bir kabuk başlatın ve sanal ortamınızı yeniden kaynaklayın.


1
Benim sorunum oldu: taze venv yenilemeden yüklemek
donduruldu

4

Benim durumumda, içe aktarma hatası oluştu çünkü paket aynı ada sahip başka bir paketi / dizini işaret ediyor ve yolu aslında istediğim klasörün bir seviye üstünde. Sanırım bu, bazı kişilerin neden _ init'i kaldırması gerektiğini de açıklıyor _.py'yi kaldırırken diğerlerinin de eklemesi gerektiğini açıklıyor.

Karşılaştırmak için hem konsola hem de komut dosyalarına print(the_root_package.__path__)(sonrasına import the_root_package) koydumpythonpytestFarkı

ALT SATIR: Bunu yaptığınızda python, içe aktardığınız paket çalıştırdığınızdaki paketten farklı olabilir pytest.


2

Yukarıdaki cevap benim için çalışmıyor. Ben sadece modülün mutlak yolunu (test modülünüzün) sys.pathüstüne bulunmayan mutlak yolu ekleyerek çözdüm test_xxx.py, örneğin:

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

1
Bu satırları üstüme test_main.pykoymak yerine, conftest.pytest rehberime koydum ve işe yaradı. Dosya çöpü yerine programlı bir çözüm sağladığınız için teşekkür ederiz.
Cameron Hudson

2

Başlangıçta python 2.7'de geliştirilen ve şimdi python 3.x'e taşınan python koduyla ilgiliyse, sorun muhtemelen bir içe aktarma sorunuyla ilgilidir.

örneğin base, aynı dizinde bulunan bir dosyadan bir nesneyi içe aktarırken, bu python 2.x'te çalışır:

from base import MyClass

python 3.x'te basetam yol ile değiştirmelisiniz, .base aksi takdirde yukarıdaki soruna neden olur. o zaman dene:

from .base import MyClass

2

Bugün bu sorunu yaşıyordum ve arayarak çözdüm python -m pytest proje dizinimin kökünden çözdüm.

pytestAynı yerden aramak hala sorunlara neden oluyordu.

Proje dizinim şu şekilde düzenlenmiştir:

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

Modül routesşu şekilde içe aktarıldı test_routes.py:from server.routes.routes import Routes

Umarım yardımcı olur!


Hatırlatma için teşekkürler, geçmişte bu numarayı kullanmak zorunda kaldım ve bu pytest belgelerinde var.
Jason R Stevens CFA

1

Başka bir özel durum:

Toksik kullanırken sorun yaşadım. Bu yüzden programım iyi gitti, ancak toksin yoluyla yapılan birim testleri şikayet etmeye devam etti. Paketleri kurduktan sonra (program için gerekli) tox.ini dosyasındaki birim testlerinde kullanılan paketleri ayrıca belirtmeniz gerekir.

[testenv]
deps =
    package1
    package2 
...

1

Bunu VSCode kullanarak alıyordum. Bir conda ortamım var. VScode python uzantısının yaptığım güncellemeleri görebileceğini sanmıyorum.

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:

Koşmak zorundaydım pip install ./ --upgrade


Bu pip komutu bir hata döndürüyor:Directory './' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.
Derek

1

Conftest.py dosyanızı düzenleyin ve aşağıdaki kod satırlarını ekleyin:

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

Test durumunu terminal üzerinden çalıştırmaya çalışıyorsanız, aşağıdaki örneği kullanın:

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

NameError: name 'file' is not defined- dosya neye eşit olmalıdır?
Koshmaar

1

Python'un ithalat sistemi için bir başka büyük kazanç. Bence fikir birliği olmamasının sebebi, neyin işe yarayacağının muhtemelen çevrenize ve onun üzerinde kullandığınız araçlara bağlı olmasıdır.

Bunu, bir conda ortamında, Python 3.8'de Windows altındaki test gezgininde VS Code'dan kullanıyorum.

Çalışmam gereken kurulum:

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

Bu kurulum altında intellisense çalışır ve test keşfi de yapar.

Burada önerildiği gibi, başlangıçta aşağıdakileri denediğimi unutmayın .

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

Bunu VS Code'dan çalıştırmanın bir yolunu bulamadım çünkü srcklasör içe aktarma sisteminin aklını uçurdu. Bunu komut satırından çalıştırmanın bir yolu olduğunu hayal edebiliyorum. Nispeten yeni bir Python programlamaya dönüştüğü için bana COM ile çalışma konusunda nostaljik bir his veriyor, ancak biraz daha az eğlenceli.


1

Bu konudaki 2 sentim: sanal ortamları kullanmıyorsanız pytest şans eseri başarısız olacaktır. Bazen işe yarayacak, bazen çalışmayacaktır.

Bu nedenle çözüm şudur:

  • pip uninstall ile pytest'i kaldırın
  • venvini yarat
  • venvini etkinleştir
  • pip proje yolunuzu düzenlenebilir modda kurun, böylece pytest tarafından bir modül olarak ele alınacaktır (aksi takdirde, pytest dahili içe aktarmalarınızı bulmayacaktır). Bunun için bir setup.py dosyasına ihtiyacınız olacak
  • pytest dahil paketlerinizi kurun
  • sonunda testlerini yap

Windows PowerShell kullanan kod:

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

En sonunda

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

Pip install -e için setup.py'ye bir örnek:

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

Herhangi bir __init__.pydosyayı kaldırmanız gerektiğini söyleyen gönderilere katılmıyorum . Bunun yerine yapmanız gereken şey sys.path.

sys.pathKodu normal şekilde çalıştırırken yazdırdığınız bir deneme çalıştırın. Ardından sys.pathkodu pytest aracılığıyla çalıştırırken yazdırın. Sanırım bu iki yol arasında bir fark olduğunu, dolayısıyla pytest'in neden kırıldığını göreceksiniz.

Bunu düzeltmek için, ilk denemenin yolunu ikincinin 0. dizinine ekleyin.

Deney 1'in '/usr/exampleUser/Documents/foo'ilk unsuru olalım print(sys.path).

Sorununuzu çözmesi gereken kod aşağıdadır:

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

Bunu, gerçek ithalat beyanınızdan önce dosyanızın en üstüne koyun.

Kaynak: Bununla kendim ilgileniyordum ve yukarıdaki süreç sorunu çözdü.


1

Her şeyi aynı tuttu ve sadece kök klasöre boş bir test dosyası ekledim .. Çözdü

İşte bulgular, bu sorun beni bir süredir gerçekten rahatsız etti. Klasör yapım

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

ve pytest ModuleNotFoundError ile şikayet eder ve İPUCU verir - test modüllerinizin / paketlerinizin geçerli Python adlarına sahip olduğundan emin olun.

Mathsapp ve testler dizini ile aynı seviyede bir sahte test dosyası tanıttım. Dosya hiçbir şey içermiyordu. Şimdi pytest şikayet etmiyor.

Dosyasız sonuç

$ 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 ===============================

Dosya ile sonuçlar

$ 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 ==============================

Bu, bu konuyla uzun bir süre sonra benim için çalıştı. Pytest proje köküne ilk test dosyasını bulduğu yerde muamele ediyor gibi görünüyor? elbette bu bir hata mı?
oooyaya

1

PYTHONPATHTestlerimi çalıştırdığım belirli yapılandırma için Ortam Değişkenlerini ayarlayarak sorunumu çözdüm.

PyCharm'da test dosyasını görüntülerken:

  1. Ctrl+ Shift+A
  2. Tür Edit Configurations
  3. PYTHONPATHOrtam> Ortam değişkenlerinizi ayarlayın .

1

conftest.pyProje kök dizinine boş bir dosya koyun , çünkü pytestbir conftest.py bulduğunda, sys.path'i conftestmodüle ederek modülden bir şeyler içe aktarabilir . Genel bir dizin yapısı şunlar olabilir:

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

1

Benzer bir sorun vardı ve __init__.pytestler dizini altına dosya eklediğimde çalıştı .


0

Python, Python okurken paketi bir Python modülü olarak okumuyor olabilir (muhtemelen yol sorunları nedeniyle). Pytest betiğinin dizinini değiştirmeyi veya modülü açıkça PYTHONPATH'ınıza eklemeyi deneyin.

Ya da makinenizde iki Python sürümü kurulu olabilir. Pytest ve çalıştırdığınız python kabuğu için Python kaynağınızı kontrol edin. Farklı iseler (yani Python 2 vs 3), source activatemodülün kurulu olduğu aynı python için kurulu pytest'i çalıştırdığınızdan emin olmak için kullanın .


0

Her şeyi deneyen ve hala hata alan herkes için bir işim var.

Gelen pytest kurulu olduğu klasöre gidin pytest-env klasöründe.

Pyvenv.cfg dosyasını açın .

Dosya değişiklik ise şunlardır-sistem-site-paketleri gelen YANLıŞ için gerçek .

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

Umarım işe yarar. Oy vermeyi unutmayın.


0

Zaten .pyc dosyalarınız varsa, onları silmeyi deneyin.

Bugün bu problemle karşılaşıyorum, işte olanlar:

ilk olarak mac'da pytest çalıştırıyorum (bu pyc dosyalarını oluşturacak) sonra proje dizini bağlanmış bir docker container (işletim sistemi alpine) başlatıyorum ve sonra pytest'i container'da çalıştırmayı denediğimde ImportError oluyor. tüm pyc dosyalarını temizledikten sonra artık hata yok.

Umarım bu yardımcı olabilir.


0

Eğer bir ihtiyacın olursa init sizin klasörde .py dosyasını klasörün ve sil bir kopyası yapmak init o birinde .py yerel projeler için çalışıyor sizin testler. Testi düzenli olarak çalıştırmanız gerekiyorsa, init .py dosyanızı ayrı bir dosyaya taşıyıp taşıyamayacağınıza bakın .


0

[Çözüldü] Doğrudan kaldırma / ekleme çözümüne geçmeden önce __init__.py, sınıflarınızda içe aktarmanın nasıl yapıldığına da bakmak isteyebiliriz. Aslında, sadece __init__.pysorunun bu olabileceğini düşünerek bir günümü kaybettim :) Ancak, bu oldukça bilgilendiriciydi.

Benim durumumda, sınıfları bir python sınıfından başka bir python sınıfına çağırmanın yanlış yolu ImportError . Sınıfların / modüllerin çağrılma şekli düzeltildi ve cazibe gibi çalıştı. Umarım bu başkalarına da yardımcı olur.

Ve evet, benzer bir hata için, kodun nasıl yazıldığına bağlı olarak farklı çözümlerimiz olabilir. Kendi kendine hata ayıklamaya daha fazla zaman harcamak daha iyidir. Alınan Ders :) Mutlu kodlamalar !!!


1
Yanlış yol ve doğru yoldan bazı örnekler verebilir misiniz?
Lurifaxel

0

Benim durumumda bir konteynerde çalışıyorum ve ne yazık ki pytest benim python3 yorumlayıcım yerine python2.7 kullanma eğiliminde.

Benim durumumda bu işe yaradı:

python3 -m pytest

Klasör yapım

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

-1

Tüm testlerimi bir testler klasörüne yerleştirmiştim ve aynı hatayı alıyordum. Bunu , şu klasöre bir init .py ekleyerek çözdüm:

.
|-- 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.