Erro de importação do nariz do Python

120

Não consigo obter a estrutura de teste do nariz para reconhecer os módulos abaixo do meu script de teste na estrutura do arquivo. Eu configurei o exemplo mais simples que demonstra o problema. Vou explicar isso abaixo.

Aqui está a estrutura do arquivo do pacote:

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

foo.py contém:

def dumb_true():
    return True

tests / test_foo.py contém:

import foo

def test_foo():
    assert foo.dumb_true()

Ambos os arquivos init .py estão vazios

Se eu executar nosetests -vvno diretório principal (onde está foo.py), eu obtenho:

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)

Eu recebo o mesmo erro quando executo de dentro do diretório tests /. De acordo com a documentação e um exemplo que encontrei, o nariz deve adicionar todos os pacotes-pai ao caminho e ao diretório a partir do qual ele é chamado, mas isso não parece estar acontecendo no meu caso.

Estou executando o Ubuntu 8.04 com Python 2.6.2. Criei e instalei o nariz manualmente (não com o setup_tools), se isso importa.

halfak
fonte

Respostas:

226

Você tem um __init__.pyno seu diretório de nível superior. Isso faz com que seja um pacote. Se você removê-lo, você nosetestsdeve funcionar.

Se você não removê-lo, precisará alterar seu importpara import dir.foo, onde diré o nome do seu diretório.

ire_and_curses
fonte
7
Entendi. Muito obrigado! Eu gostaria de votar, mas aparentemente preciso de mais reputação.
halfak 18/06/10
4
Não se preocupe. Bem-vindo ao StackOverflow! Você pode marcar a marca de seleção verde à esquerda se a resposta resolver seu problema.
ire_and_curses
2
@halfak: Tenha outro voto positivo na sua pergunta então. Você também (na sua resposta), @ire.
Mark Rushakoff
1
Entendi. Obrigado pela dica :)
halfak 22/06
5
Eu tenho uma situação em que os testes funcionam se init .py no diretório raiz - no entanto, eu preciso que esse arquivo esteja lá e importo modelos. <model_name> ainda não foi encontrado. Teste está dentro de um diretório tests / , e o modelo que estou tentando testar está dentro de models / directory ... qualquer ajuda seria apreciada.
precisa
32

Você está em um virtualenv? No meu caso, nosetestsfoi o /usr/bin/nosetestsque estava usando /usr/bin/python. Os pacotes no virtualenv definitivamente não estarão no caminho do sistema. O seguinte corrigiu isso:

source myvirtualenv/activate
pip install nose
which nosetests
/home/me/myvirtualenv/bin/nosetests
Toppur
fonte
2
Meu também. Obrigado, economizou muito tempo.
precisa saber é o seguinte
3
para mim nosetestsfoi armazenado em cache bashno sistema /usr/local/bin(enquanto which nosetestsestava dando o resultado apropriado). Eu usei isso para limpá-lo.
Raffi
5
Além disso, tive que desativar e ativar meu virtualenv.
Bengt
Eu tive um problema com o PS1 = $ {PS1: -} definido ao ativar o virtualenv (para superar erros em variáveis ​​não definidas). Depois de remover isso e mudar para definir + u , não tive mais problemas.
Juuso Ohtonen 17/01/19
13

Para aqueles que encontrarem essa pergunta mais tarde: Recebo o erro de importação se não houver um __init__.pyarquivo no meu diretório de testes.

Minha estrutura de diretórios era assim:

./tests/
  ./test_some_random_stuff.py

Se eu fizesse testes nos:

nosetests -w tests

Daria o ImportErrorque todo mundo está vendo. Se eu adicionar um __init__.pyarquivo em branco, ele funcionará perfeitamente:

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

Outro problema em potencial parece ser hífens / traços na árvore de diretórios. Corrigi recentemente um problema no ImportError renomeando um diretório de sub-dirpara sub_dir.

Aron Ahmadia
fonte
1
@ Adam, você percebe a diferença entre identificadores de variáveis ​​e nomes de arquivos?
Nakilon
Sim ... Eu sempre tenho um arquivo semelhante ao FooTests.py e, por algum motivo, não gostou ... Renomeei o nome Foo_Tests.py e funcionou ... parece um pouco complicado.
Birdman
3

Obviamente, se você tiver um erro de sintaxe no módulo sendo importado, isso causará isso. Para mim, o problema surgiu quando eu tinha um backup de um arquivo de testes com um caminho como module / tests.bak.py no mesmo diretório que tests.py. Além disso, para lidar com o problema do pacote / módulo init em um aplicativo Django, você pode executar o seguinte (em um shell bash / OSX) para garantir que não haja nenhum arquivo .pyc init por aí:

find . -name '*.pyc' -delete
fogão
fonte
3

Recebi essa mensagem de erro porque executo o nosetestscomando no diretório errado.

Bobo, mas acontece.

Eyal Levin
fonte
Você pode adicionar alguns detalhes à sua resposta? De que diretório você o executou? Por que isso está errado? Qual seria o diretório certo? A execução nosetestsem um diretório sem nenhum teste resultará em Ran 0 testsnenhum erro de importação. Na sua forma atual, essa resposta não é útil.
gerrit 19/02/19
2

Acabei de encontrar mais uma coisa que pode causar esse problema: nomeação de testes no formulário testname.test.py. Esse extra .confunde o nariz e leva a importar coisas que não deveria. Suponho que seja óbvio que o uso de convenções de nomenclatura de teste não convencionais vá quebrar as coisas, mas achei que poderia valer a pena notar.

7yl4r
fonte
2

Por exemplo, com a seguinte estrutura de diretórios, se você deseja executar nosetestsem m1, m2ou m3para testar algumas funções em n.py, você deve usar from m2.m3 import nno test.py.

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

Apenas para concluir a pergunta: se você está enfrentando uma estrutura como esta:

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

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

E talvez você queira executar o teste a partir de um caminho fora do projeto, inclua o caminho do projeto dentro do seu PYTHONPATH.

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

cole-o dentro do seu .profile. Se você estiver em um ambiente virtual, cole-o dentro do ativar em sua raiz venv

Rainelz
fonte