Помилка імпорту носа Python


121

Я не можу отримати рамку тестування носа для розпізнавання модулів під моїм тестовим сценарієм у структурі файлів. Я створив найпростіший приклад, який демонструє проблему. Я поясню це нижче.

Ось структура файлу пакета:

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

foo.py містить:

def dumb_true():
    return True

тести / test_foo.py містить:

import foo

def test_foo():
    assert foo.dumb_true()

Обидва файли init .py порожні

Якщо я запускаю nosetests -vvв основний каталог (де foo.py), я отримую:

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)

Я отримую таку ж помилку, коли біжу зсередини тестів / каталогу. Відповідно до знайденої нами документації та прикладу , ніс повинен додавати всі батьківські пакети до шляху, а також до каталогу, з якого він викликається, але це, схоже, не відбувається в моєму випадку.

Я запускаю Ubuntu 8.04 з Python 2.6.2. Я створив і встановив ніс вручну (не з setup_tools), якщо це має значення.

Відповіді:


226

Ви маєте __init__.pyв своєму каталозі верхнього рівня. Це робить його пакетом. Якщо ви виймете його, ви nosetestsповинні працювати.

Якщо ви не видалите його, ви повинні змінити importTo import dir.foo, де dirце ім'я каталогу.


7
Це і дісталося. Велике спасибі! Я б голосував, але, мабуть, мені потрібно більше репутації.
халф

4
Не хвилюйтесь. Ласкаво просимо до StackOverflow! Ви можете поставити галочку зеленої галочки зліва, якщо відповідь вирішить вашу проблему.
ire_and_curses

2
@halfak: Тоді поставте ще один запит на запитання. Ви теж (на вашу відповідь), @ire.
Марк Рушакофф

1
Зрозумів. Дякую за підказку :)
півроку

5
У мене ситуація, коли тести працюють, якщо init .py в кореневому каталозі - однак, мені потрібен цей файл, а імпорт моделей. <model_name> все ще не знайдено. Тест знаходиться в тесті / каталозі, а модель, яку я намагаюся протестувати, знаходиться всередині моделей / каталогу ... будь-яка допомога буде вдячна.
Кіс Бріггс

32

Ви у віртуолі? У моєму випадку це nosetestsбув той /usr/bin/nosetests, хто користувався /usr/bin/python. Пакети в virtualenv точно не будуть в системному шляху. Виправлено наступне:

source myvirtualenv/activate
pip install nose
which nosetests
/home/me/myvirtualenv/bin/nosetests

2
Також моя. Дякую, заощадили багато часу.
jskulski

3
для мене nosetestsкешировано bashсистемою один в /usr/local/bin(при цьому which nosetestsдавав належний результат). Я використав це для очищення.
Раффі

5
Крім того, мені довелося деактивувати та активувати свій virtualenv.
Бенгт

У мене виникла проблема із встановленням PS1 = $ {PS1: -} при активації virtualenv (для подолання помилок на невстановлених змінних). Після видалення цього і переходу на встановлення + u у мене більше не було проблем.
Juuso Ohtonen

13

Тим із вас, хто знайде це питання пізніше: я отримую помилку імпорту, якщо у мене немає __init__.py у мене в каталозі тестів файлу.

Структура мого каталогу була така:

./tests/
  ./test_some_random_stuff.py

Якщо я бігла носові протести:

nosetests -w tests

Це дало б те, ImportErrorщо бачать усі інші. Якщо я додам пустий __init__.pyфайл, він працює чудово:

./tests/
  ./__init__.py
  ./test_some_random_stuff.py

10

Ще одна потенційна проблема - це дефіси / тире в дереві каталогів. Нещодавно я вирішив проблему з імпортом ImportError, перейменувавши каталог sub-dirу sub_dir.



1
@Aman, ти розумієш різницю між ідентифікаторами змінних та іменами файлів?
Накілон

Так ... У мене завжди є файл, схожий на FooTests.py, і він чомусь не сподобався ... Я перейменований на Foo_Tests.py, і він працював ... здається трохи вибагливим.
Birdman

3

Звичайно, якщо у імпортованому модулі є синтаксична помилка, це спричинить це. Для мене проблема підняла голову, коли у мене було резервне копіювання тестового файлу з таким шляхом, як module / testing.bak.py, у тому ж каталозі, що і test.py. Також, щоб вирішити проблему пакета / модуля init у додатку Django, ви можете запустити наступне (в оболонці bash / OSX), щоб переконатися, що у вас немає файлів init .pyc:

find . -name '*.pyc' -delete

3

Я отримав це повідомлення про помилку, оскільки я запускаю nosetestsкоманду з неправильного каталогу.

Нерозумно, але буває.


Чи можете ви додати якісь деталі у відповідь? З якого каталогу ви запустили його? Чому це неправильно? Який би був правильний каталог? Якщо працювати nosetestsв каталозі без тестів, це призведе до Ran 0 testsпомилки імпорту. У теперішній формі ця відповідь не є корисною.
Герріт

2

Я просто натрапив на ще одне, що може спричинити цю проблему: називання тестів у формі testname.test.py. Це додатково .бентежить ніс і призводить до того, що він імпортує речі, які він не повинен. Я припускаю, що може бути очевидним, що використання нетрадиційних конвенцій про іменування може порушити справи, але я подумав, що це варто зауважити.


2

Наприклад, з наступною структурою каталогів, якщо ви хочете працювати nosetestsв m1, m2або m3перевірити деякі функції в n.py, ви повинні використовувати from m2.m3 import nв test.py.

m1
└── m2
    ├── __init__.py
    └── m3
        ├── __init__.py
        ├── n.py
        └── test
            └── test.py

1

Просто для завершення питання: Якщо ви боретеся з такою структурою:

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

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

І, можливо, ви хочете запустити тест із шляху поза проектом, включіть шлях свого проекту всередину вашого PYTHONPATH.

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

вставити його у свій .profile. Якщо ви знаходитесь у віртуальному середовищі, вставте його всередину активації у вашому корені venv

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.