pytest tidak dapat mengimpor modul sementara python bisa


115

Saya sedang mengerjakan paket dengan Python. Saya menggunakan virtualenv. Saya mengatur jalur ke root modul di jalur .pth di virtualenv saya, sehingga saya dapat mengimpor modul dari paket sambil mengembangkan kode dan melakukan pengujian (Pertanyaan 1: apakah ini cara yang baik untuk dilakukan?). Ini berfungsi dengan baik (ini adalah contoh, ini adalah perilaku yang saya inginkan):

(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

Namun, jika saya mencoba menggunakan PyTest, saya mendapatkan beberapa pesan kesalahan impor:

(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

Saya agak bingung, sepertinya ini menunjukkan kesalahan impor, tetapi Python tidak masalah jadi mengapa ada masalah khusus dengan PyTest? Adakah saran untuk alasan / perbaikan (Pertanyaan 2)? Saya mencari di Google dan menumpuk kesalahan 'ImportError: tidak dapat mengimpor' untuk PyTest, tetapi klik yang saya dapatkan terkait dengan jalur python yang hilang dan perbaikan untuk ini, yang tampaknya bukan masalah di sini. Ada saran?

Jawaban:


118

Menemukan jawabannya:

JANGAN menaruh __init__.pyfile di folder yang berisi TESTS jika Anda berencana menggunakan pytest. Saya punya satu file seperti itu, menghapusnya menyelesaikan masalah.

Ini sebenarnya terkubur di komentar pada jawaban kedua dari masalah PATH dengan pytest 'ImportError: Tidak ada modul bernama YadaYadaYada' jadi saya tidak melihatnya, semoga lebih terlihat di sini.


45
Lucu. Saya memiliki masalah yang sama dan saya harus menambahkan init .py ke folder tes saya.
Ev.

5
Ya, ini bukan solusi umum (meskipun itu dalam kasus Anda), untuk memahami mengapa ini harus dibaca: docs.pytest.org/en/latest/goodpractices.html#test-package-name
juan

1
Informasi ini SALAH dan menyesatkan! Setelah menambahkan init .py ke dalam folder uji semuanya bekerja dengan baik
Leonardo Ostan

1
@LeonardoOstan mungkin salah untuk Anda, tetapi bukan berarti informasi ini salah secara umum. Dalam kasus saya, ini memecahkan masalah.
Desprit

80

Saya tidak bisa mengatakan saya mengerti mengapa ini berhasil, tetapi saya memiliki masalah yang sama dan tes berfungsi dengan baik jika saya menjalankan python -m pytest.

Saya berada di virtualenv, dengan pytest juga tersedia secara global:

(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
Juga melakukan pekerjaan untuk saya, masalahnya ,, ini dijalankan oleh versi python yang ditentukan, bukan v.env Anda.
Nebulosar

12
salah satu alasannya mungkin python -m pytest [...]"juga akan menambahkan direktori saat ini ke sys.path".
minusf

Memiliki hal yang sama di Windows 10, dan menjalankan python -m pytest menyelesaikannya
Duccio

Ini bekerja juga di dalam lingkungan virtual saya yang harus saya jalankanpython3 -m pytest
Rishi Raj

Berdasarkan komentar oleh @minusf yang saya gunakan PYTHONPATH=.:./src pytestsebagai target sasaran.
jan groth

29

Saya baru saja menyelesaikan ini dengan menghapus __init__.py di root proyek saya:

.
├── __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
Jawaban yang diterima __init__.py file in a folder containing TESTStidak menyelesaikan masalah saya. Yang ini berhasil. Saya kira itu karena hierarki file.
smido

Saya telah menghapus __init__.pyfile. Saya masih menghadapi masalah. Menambahkan file conftest.py ke direktori root berhasil untuk saya.
Vijay Sali

Saya berharap conftest.py ada di / tes bukan di root
Aaron McMillin

Mendapatkan file conftest.py ke direktori root juga memperbaikinya untuk saya. Tidak memiliki file init .py di direktori tes
Perbarui

2
Solusi ini berfungsi untuk saya, tetapi apakah ada yang tahu ini akan menyebabkan kesalahan impor?
Aldo Okware

19

Saya memiliki masalah yang sama tetapi karena alasan lain selain yang disebutkan:

Saya telah menginstal py.test secara global, sedangkan paket diinstal di lingkungan virtual.

Solusinya adalah menginstal pytestdi lingkungan virtual. (Jika shell Anda mencirikan file yang dapat dieksekusi, seperti yang dilakukan Bash, gunakan hash -r, atau gunakan jalur lengkap ke py.test)


2
Baru sadar saya memiliki masalah licik yang sama, menggunakan anaconda. Saya lupa menambahkan pytestvirtualenv yang dibuat oleh conda, namun pytestitu tersedia di lingkungan root anaconda. Oleh karena itu pytest dapat ditemukan, tetapi tidak ada paket yang diinstal di lingkungan.
Overdrivr

1
Saya memiliki masalah yang sama. pytest diinstal secara global dan bukan di virtualenv. pip3 install pytestdi dalam virtualenv memperbaiki masalah.
Ankit Singh

7

Masalah ini akan terjadi jika Anda memiliki tests.pyfile dan folder tes dengan tests/__init__.py.

Selama pengumpulan pytest menemukan foldernya, tetapi ketika mencoba mengimpor file uji dari folder, tests.pyfile akan menyebabkan masalah impor.

Untuk memperbaikinya cukup hapus tests.pyfile dan letakkan semua tes Anda di dalam tests/folder.

Untuk kasus khusus Anda, perbaikannya akan tepat:

  • Hapus file /home/zz/Desktop/GitFolders/rc/tests.py
  • Pastikan /home/zz/Desktop/GitFolders/rc/tests/__init__.pyada

4

Saya mengalami masalah yang sama, kesalahan yang sama persis, tetapi penyebabnya berbeda. Saya menjalankan kode pengujian dengan baik, tetapi terhadap modul versi lama. Dalam versi sebelumnya dari kode saya, satu kelas ada, sedangkan yang lainnya tidak. Setelah memperbarui kode saya, saya harus menjalankan perintah berikut untuk menginstalnya.

sudo pip install ./ --upgrade

Setelah menginstal modul yang diperbarui menjalankan pytest menghasilkan hasil yang benar (karena saya menggunakan basis kode yang benar).


1
Ini berhasil untuk saya! Modul saya pada saat yang sama dipasang sebagai perpustakaan di kontainer buruh pelabuhan yang saya gunakan untuk menjalankan pytest. Saat menjalankan interpreter python, ia akan menemukan kode yang diperbarui, tetapi pytest akan terus menemukan kode seperti saat perpustakaan pertama kali diinstal. Menjalankan pip install ./ --upgradememperbarui versi lib yang diinstal dengan kode terbaru, dan mengaktifkan pytest untuk menemukan versi terbaru ini juga.
FaustoW

4

Dalam kasus saya, kesalahan impor terjadi karena paket mengarah ke paket / direktori lain dengan nama yang sama dan jalurnya satu tingkat di atas folder yang sebenarnya saya inginkan. Saya rasa ini juga menjelaskan mengapa beberapa orang perlu menghapus _ init _.py sementara yang lain perlu menambahkan kembali.

Saya hanya meletakkan print(the_root_package.__path__)(setelah import the_root_package) di kedua pythonkonsol dan pytestskrip untuk membandingkan perbedaannya

BAWAH BARIS: Ketika Anda melakukannya python, paket yang Anda impor mungkin berbeda dari paket saat Anda menjalankan pytest.


3

Instal paket ke dalam lingkungan virtual Anda.
Kemudian mulai shell baru dan sumber lingkungan virtual Anda lagi.


1
Itulah masalah saya: penginstalan baru tanpa memuat ulang venv
dibekukan pada

2

Jawaban di atas tidak berhasil untuk saya. Saya baru saja menyelesaikannya dengan menambahkan jalur absolut dari modul yang tidak ditemukan sys.pathdi bagian atas test_xxx.py(modul pengujian Anda), seperti:

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

1
Alih-alih meletakkan baris-baris ini di atas saya test_main.py, saya memasukkannya ke dalam conftest.pydirektori pengujian saya, dan itu berhasil. Terima kasih telah memberikan solusi terprogram, bukan sampah file.
Cameron Hudson

2

Jika terkait dengan kode python yang awalnya dikembangkan di python 2.7 dan sekarang bermigrasi ke python 3.x maka masalahnya mungkin terkait dengan masalah impor.

misalnya saat mengimpor objek dari file: baseyang terletak di direktori yang sama, ini akan berfungsi di python 2.x:

from base import MyClass

di python 3.x Anda harus mengganti dengan basepath lengkap atau .base tidak melakukannya akan menyebabkan masalah di atas. jadi cobalah:

from .base import MyClass

2

Saya mengalami masalah ini hari ini dan menyelesaikannya dengan menelepon python -m pytest dari root direktori proyek saya.

Panggilan pytest dari lokasi yang sama masih menyebabkan masalah.

Direktori Proyek saya diatur sebagai:

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

Modul routesdiimpor di sayatest_routes.py as:from server.routes.routes import Routes

Semoga membantu!


Terima kasih atas pengingatnya, saya harus menggunakan trik di masa lalu dan itu ada di dokumentasi pytest.
Jason R Stevens CFA

1

Kasus khusus lainnya:

Saya mengalami masalah saat menggunakan racun. Jadi program saya berjalan dengan baik, tetapi unittests via tox terus mengeluh. Setelah menginstal paket (diperlukan untuk program), Anda perlu menentukan paket tambahan yang digunakan dalam unittests di tox.ini

[testenv]
deps =
    package1
    package2 
...

1

Saya mendapatkan ini menggunakan VSCode. Saya memiliki lingkungan conda. Saya tidak berpikir ekstensi python VScode dapat melihat pembaruan yang saya buat.

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:

Saya harus lari pip install ./ --upgrade


Perintah pip itu mengembalikan kesalahan:Directory './' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.
Derek

1

Edit conftest.py Anda dan tambahkan baris kode berikut:

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

Dan jika mencoba menjalankan kasus uji melalui terminal, gunakan contoh berikut:

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

NameError: name 'file' is not defined- apa yang harus mengajukan sama dengan?
Koshmaar

1

Kemenangan besar lainnya untuk sistem impor Python. Saya pikir alasan tidak ada konsensus adalah bahwa apa yang berhasil mungkin tergantung pada lingkungan Anda dan alat yang Anda gunakan di atasnya.

Saya menggunakan ini dari VS Code, dalam test explorer di bawah Windows di lingkungan conda, Python 3.8.

Penyiapan yang harus saya lakukan adalah:

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

Di bawah pengaturan ini, intellisense bekerja dan begitu pula penemuan pengujian.

Perhatikan bahwa saya awalnya mencoba yang berikut, seperti yang direkomendasikan di sini .

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

Saya tidak dapat menemukan cara untuk membuat ini bekerja dari VS Code karena srcfoldernya hanya meniup pikiran sistem impor. Saya bisa membayangkan ada cara untuk membuatnya bekerja dari baris perintah. Sebagai orang yang relatif baru beralih ke pemrograman Python, ini memberi saya perasaan nostalgia bekerja dengan COM, tetapi menjadi sedikit kurang menyenangkan.


1

2 sen saya ini: pytest akan gagal secara kebetulan jika Anda tidak menggunakan lingkungan virtual. Terkadang itu akan berhasil, terkadang tidak.

Oleh karena itu, solusinya adalah:

  • hapus pytest dengan pip uninstall
  • buat venv Anda
  • aktifkan venv Anda
  • pip install jalur proyek Anda dalam mode editable, sehingga akan diperlakukan oleh pytest sebagai modul (jika tidak, pytest tidak akan menemukan impor internal Anda). Anda akan membutuhkan file setup.py untuk itu
  • instal paket Anda, termasuk pytest
  • akhirnya, jalankan pengujian Anda

Kode, menggunakan 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

Lalu akhirnya

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

Contoh setup.py, untuk 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

Saya tidak setuju dengan postingan yang mengatakan bahwa Anda harus menghapus __init__.pyfile apa pun . Yang harus Anda lakukan adalah mengubahsys.path .

Jalankan eksperimen tempat Anda mencetak sys.pathsaat menjalankan kode seperti biasa. Lalu cetaksys.path sambil menjalankan kode melalui pytest. Saya pikir Anda akan menemukan bahwa ada perbedaan antara kedua jalur ini, karena itulah pytest pecah.

Untuk memperbaikinya, masukkan jalur dari eksperimen pertama di indeks ke-0 dari eksperimen kedua.

Membiarkan '/usr/exampleUser/Documents/foo'menjadi elemen pertama print(sys.path)untuk percobaan 1.

Di bawah ini adalah kode yang seharusnya memperbaiki masalah Anda:

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

Letakkan ini di bagian atas file Anda, sebelum pernyataan impor Anda yang sebenarnya.

Sumber: Saya menangani ini sendiri dan proses di atas menyelesaikannya.


1

Biarkan semuanya tetap sama dan baru saja menambahkan file tes kosong di folder root .. Selesaikan

Berikut temuannya, masalah ini benar-benar mengganggu saya untuk sementara waktu. Struktur folder saya dulu

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

dan pytest akan mengeluh dengan ModuleNotFoundError dan memberikan PETUNJUK - pastikan modul / paket pengujian Anda memiliki nama Python yang valid.

Saya memperkenalkan file uji tiruan pada tingkat yang sama dengan direktori mathsapp dan tes. File tersebut tidak berisi apa-apa. Sekarang pytest tidak mengeluh.

Hasil tanpa file

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

Hasil dengan file

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

ini berhasil untuk saya setelah sekian lama dengan masalah ini. Sepertinya pytest memperlakukan root proyek seperti di mana pun ia menemukan file pengujian pertama? apakah ini bug?
oooyaya

1

Saya memecahkan masalah saya dengan mengatur PYTHONPATHdi Variabel Lingkungan untuk konfigurasi spesifik yang saya gunakan untuk pengujian.

Saat Anda melihat file pengujian di PyCharm:

  1. Ctrl+ Shift+A
  2. Tipe Edit Configurations
  3. Setel Anda di PYTHONPATHbawah variabel Lingkungan> Lingkungan.

1

Cukup letakkan conftest.pyfile kosong di direktori root proyek, karena ketika pytestmenemukan conftest.py, itu memodifikasi sys.path sehingga dapat mengimpor barang dari conftestmodul. Struktur direktori umum dapat berupa:

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

1

Memiliki masalah serupa dan berhasil ketika saya menambahkan __init__.pyfile di bawah direktori tes.


0

Bisa jadi Pytest tidak membaca paket sebagai modul Python sedangkan Python membaca (kemungkinan karena masalah jalur). Coba ubah direktori skrip pytest atau tambahkan modul secara eksplisit ke PYTHONPATH Anda.

Atau bisa jadi Anda memiliki dua versi Python yang diinstal di mesin Anda. Periksa sumber Python Anda untuk pytest dan untuk shell python yang Anda jalankan. Jika berbeda (yaitu Python 2 vs 3), gunakan source activateuntuk memastikan bahwa Anda menjalankan pytest yang diinstal untuk python yang sama dengan tempat modul diinstal.


0

Bagi siapa pun yang mencoba segalanya dan masih mendapatkan kesalahan, saya punya solusi.

Di folder tempat pytest diinstal , buka pytest-env folder .

Buka file pyvenv.cfg .

Dalam file, ubah include-system-site-packages dari false menjadi true .

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

Semoga berhasil. Jangan lupa untuk memilih.


0

Jika Anda sudah memiliki file .pyc, coba hapus.

Hari ini, saya mengalami masalah ini, inilah yang terjadi:

pertama saya menjalankan pytest di mac (ini akan menghasilkan file pyc) kemudian saya meluncurkan kontainer buruh pelabuhan (os alpine), dengan dir proyek terpasang, dan kemudian ketika saya mencoba menjalankan pytest di kontainer, terjadi ImportError. setelah membersihkan semua file pyc, tidak ada kesalahan lagi.

Semoga bermanfaat.


0

jika Anda memerlukan file init .py di folder Anda, buat salinan folder dan hapus init .py di folder itu untuk menjalankan pengujian, ini berfungsi untuk proyek lokal. Jika Anda perlu menjalankan pengujian secara teratur, lihat apakah Anda dapat memindahkan init .py Anda ke file terpisah.


0

[Terselesaikan] Sebelum langsung beralih ke solusi penghapusan / penambahan __init__.py, kami mungkin juga ingin melihat bagaimana impor dilakukan di kelas Anda. Sebenarnya, saya kehilangan satu hari bermain-main dengan hanya __init__.pymemikirkan itu mungkin masalahnya :) Namun, itu cukup informatif.

Dalam kasus saya, itu adalah cara yang salah untuk memanggil kelas dari satu kelas python ke kelas python lain yang melempar ImportError . Memperbaiki cara kelas / modul dipanggil dan berfungsi seperti pesona. Semoga ini bisa membantu orang lain juga.

Dan ya, untuk kesalahan serupa, kami mungkin memiliki solusi yang berbeda tergantung pada bagaimana kode tersebut ditulis. Lebih baik menghabiskan lebih banyak waktu untuk self debugging. Hal yang dipelajari :) Selamat membuat kode !!!


1
Bisakah Anda memberikan beberapa contoh cara yang salah dan cara yang benar?
Lurifaxel

0

Dalam kasus saya, saya bekerja di sebuah wadah dan sayangnya pytest memiliki kecenderungan untuk menggunakan python2.7 daripada penerjemah python3 pilihan saya.

Dalam kasus saya ini berhasil:

python3 -m pytest

Struktur folder saya

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

-1

Saya telah menempatkan semua tes saya di folder tes dan mendapatkan kesalahan yang sama. Saya menyelesaikan ini dengan menambahkan init .py di folder itu seperti:

.
|-- 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.