Kesalahan Impor Hidung Python

121

Saya tidak bisa mendapatkan kerangka pengujian hidung untuk mengenali modul di bawah skrip pengujian saya dalam struktur file. Saya telah menyiapkan contoh paling sederhana yang menunjukkan masalah tersebut. Saya akan menjelaskannya di bawah.

Berikut struktur file paketnya:

./__init__.py
./foo.py
./tests
   ./__init__.py
   ./test_foo.py

foo.py mengandung:

def dumb_true():
    return True

tes / test_foo.py berisi:

import foo

def test_foo():
    assert foo.dumb_true()

Kedua file init .py kosong

Jika saya menjalankan nosetests -vvdi direktori utama (di mana foo.py berada), saya mendapatkan:

Failure: ImportError (No module named foo) ... ERROR

======================================================================
ERROR: Failure: ImportError (No module named foo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/loader.py", line 379, in loadTestsFromName
    addr.filename, addr.module)
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/importer.py", line 39, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/importer.py", line 86, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/home/user/nose_testing/tests/test_foo.py", line 1, in <module>
    import foo
ImportError: No module named foo

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)

Saya mendapatkan kesalahan yang sama ketika saya menjalankan dari dalam direktori tes /. Menurut dokumentasi dan contoh yang saya temukan, nose seharusnya menambahkan semua paket induk ke jalur serta direktori tempat ia dipanggil, tetapi ini tampaknya tidak terjadi dalam kasus saya.

Saya menjalankan Ubuntu 8.04 dengan Python 2.6.2. Saya telah membangun dan menginstal nose secara manual (bukan dengan setup_tools) jika itu penting.

Halfak
sumber

Jawaban:

226

Anda punya __init__.pydi direktori tingkat atas Anda. Itu membuatnya menjadi satu paket. Jika Anda menghapusnya, Anda nosetestsharus bekerja.

Jika Anda tidak menghapusnya, Anda harus mengubah importke import dir.foo, di mana dirnama direktori Anda.

ire_and_curses
sumber
7
Baiklah. Terimakasih banyak! Saya akan memilih, tetapi tampaknya saya membutuhkan lebih banyak reputasi.
halfak
4
Jangan khawatir. Selamat datang di StackOverflow! Anda dapat mencentang tanda centang hijau di sebelah kiri jika jawabannya menyelesaikan masalah Anda.
ire_and_curses
2
@halfak: Kalau begitu, dapatkan suara positif lain untuk pertanyaan Anda. Anda juga (atas jawaban Anda), @ire.
Mark Rushakoff
1
Mengerti. Terima kasih atas tipnya :)
halfak
5
Saya memiliki situasi di mana tes bekerja jika init .py di direktori root - namun, saya perlu file itu ada di sana, dan model impor. <model_name> masih tidak ditemukan. Test ada di dalam direktori tests / , dan model yang saya coba uji ada di dalam direktori models / ... bantuan apa pun akan dihargai.
Kees Briggs
32

Apakah Anda berada di virtualenv? Dalam kasus saya, nosetestsadalah salah satu /usr/bin/nosetestsyang digunakan /usr/bin/python. Paket-paket di virtualenv pasti tidak akan berada di jalur sistem. Hal berikut memperbaiki ini:

source myvirtualenv/activate
pip install nose
which nosetests
/home/me/myvirtualenv/bin/nosetests
toppur
sumber
2
Juga milikku. Terima kasih, menghemat banyak waktu.
jskulski
3
bagi saya di nosetests-cache oleh bashsatu sistem /usr/local/bin(sementara which nosetestsmemberikan hasil yang tepat). Saya menggunakan ini untuk membersihkannya.
Raffi
5
Selain itu, saya harus menonaktifkan dan mengaktifkan virtualenv saya.
Bengt
Saya punya masalah dengan set PS1 = $ {PS1: -} saat mengaktifkan virtualenv (untuk mengatasi kesalahan pada variabel yang tidak disetel). Setelah menghapus ini dan beralih ke set + u , saya tidak punya masalah lagi.
Juuso Ohtonen
13

Bagi Anda yang menemukan pertanyaan ini nanti: Saya mendapatkan kesalahan impor jika saya tidak memiliki __init__.pyfile di direktori pengujian saya.

Struktur direktori saya seperti ini:

./tests/
  ./test_some_random_stuff.py

Jika saya tidak melakukan uji coba:

nosetests -w tests

Itu akan memberi apa ImportErroryang dilihat orang lain. Jika saya menambahkan __init__.pyfile kosong, itu berfungsi dengan baik:

./tests/
  ./__init__.py
  ./test_some_random_stuff.py
robbrit
sumber
10

Masalah potensial lainnya tampaknya adalah tanda hubung / tanda hubung di pohon direktori. Saya baru-baru ini memperbaiki masalah ImportError hidung dengan mengganti nama direktori dari sub-dirmenjadi sub_dir.

Aron Ahmadia
sumber
1
@ Man, Anda menyadari perbedaan antara pengidentifikasi variabel dan nama file?
Nakilon
Ya ... Saya selalu memiliki file yang mirip dengan FooTests.py dan untuk beberapa alasan tidak menyukainya ... Saya mengganti namanya menjadi Foo_Tests.py dan berhasil ... sepertinya agak rewel.
Birdman
3

Tentu saja jika Anda memiliki kesalahan sintaks pada modul yang diimpor yang akan menyebabkan hal ini. Bagi saya, masalahnya muncul ketika saya memiliki cadangan file tes dengan jalur seperti module / tests.bak.py di direktori yang sama seperti tests.py. Juga, untuk menangani masalah paket / modul init dalam aplikasi Django, Anda dapat menjalankan berikut ini (dalam shell bash / OSX) untuk memastikan Anda tidak memiliki berkas .pyc init yang tergeletak di sekitar:

find . -name '*.pyc' -delete
kompor
sumber
3

Saya mendapat pesan kesalahan ini karena saya menjalankan nosetests perintah dari direktori yang salah.

Konyol, tapi terjadi.

Eyal Levin
sumber
Bisakah Anda menambahkan beberapa detail pada jawaban Anda? Dari direktori mana Anda menjalankannya? Kenapa salah Apa direktori yang benar? Berjalan nosetestsdi direktori tanpa pengujian sama sekali akan menghasilkan Ran 0 tests, bukan kesalahan impor. Dalam bentuknya yang sekarang, jawaban ini tidak berguna.
gerrit
2

Saya baru saja mengalami satu hal lagi yang mungkin menyebabkan masalah ini: penamaan tes dalam formulir testname.test.py. Ekstra itu .mengacaukan hidung dan menyebabkannya mengimpor hal-hal yang tidak semestinya. Saya rasa mungkin sudah jelas bahwa menggunakan konvensi penamaan pengujian yang tidak konvensional akan merusak banyak hal, tetapi saya pikir mungkin perlu diperhatikan.

7yl4r
sumber
2

Misalnya, dengan struktur direktori berikut, jika Anda ingin menjalankan nosetestsdi m1, m2atau m3untuk menguji beberapa fungsi dalam n.py, Anda harus menggunakan from m2.m3 import ndi test.py.

m1
└── m2
    ├── __init__.py
    └── m3
        ├── __init__.py
        ├── n.py
        └── test
            └── test.py
Che-Hsun Liu
sumber
1

Sekadar melengkapi pertanyaan: Jika Anda kesulitan dengan struktur seperti ini:

project
├── m1
    ├── __init__.py
    ├── foo1.py
    └──m2
       ├── __init__.py
       └── foo2.py

└── test
     ├── __init__.py
     └── test.py

Dan mungkin Anda ingin menjalankan pengujian dari jalur di luar proyek, termasuk jalur proyek Anda di dalam PYTHONPATH Anda.

export PYTHONPATH=$PYTHONPATH:$HOME/path/to/project

tempelkan di dalam .profil Anda. Jika Anda berada di lingkungan virtual, tempelkan di dalam aktivasi di root venv Anda

Rainelz
sumber