【问题标题】:why isn't nosetests catching what i want it to?为什么鼻子测试不能捕捉到我想要的东西?
【发布时间】:2012-03-07 04:37:24
【问题描述】:

我正在使用learn python the hard way 2nd edition 来自学编程。在exercise 46 中被指示做一些事情:

$ mkdir -p projects 
$ cd projects/
$ mkdir skeleton
$ cd skeleton
$ mkdir bin NAME tests docs

$ touch NAME/__init__.py
$ touch tests/__init__.py

这里是 setup.py 的内容:

尝试: 从 setuptools 导入设置 导入错误除外: 从 distutils.core 导入设置

config = {
    'description': 'My Project',
    'author': 'My Name',
    'url': 'URL to get it at.',
    'download_url': 'Where to download it.',
    'author_email': 'My email.',
    'version': '0.1',
    'install_requires': ['nose'],
    'packages': ['NAME'],
    'scripts': [],
    'name': 'projectname'
}

setup(**config)

测试/NAME_tests.py:

from nose.tools import *
import NAME

def setup():
    print "SETUP!"

def teardown():
    print "TEAR DOWN!"

def test_basic():
    print "I RAN!"

然后安装一些包:

  1. 来自http://pypi.python.org/pypi/pip的点子
  2. http://pypi.python.org/pypi/distribute分发
  3. 来自http://pypi.python.org/pypi/nose/的鼻子
  4. 来自http://pypi.python.org/pypi/virtualenv的virtualenv

所有这些我都没有大惊小怪(一旦我从 Windows 切换到 Ubuntu)。

Zed(LPTHW 的作者)然后说你可以通过这样做来测试你是否做对了所有事情:

 drewverlee@ubuntu:~/projects/skeleton$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.020s

OK
drewverlee@ubuntu:~/projects/skeleton$ 

太棒了!

但这就是问题所在。在 udemy 课程(在线教程课程)中,他将骨架复制到一个测试项目中(cp -r skelton foobar),他大致做了......

zedscomp/projects/foobar: >>> nosetests

然后 zed 收到类似以下的错误:

ImportError: 没有名为 NAME 的模块

那么zed就去了……

grep -r "NAME" .

(给了他)

./tests/foobar_tests.py:import NAME

然后他解释说“这是单元测试的伟大之处,因为它们会捕获这些错误(zeds 错误显然是他没有将 import NAME 重命名为 import foobar)

所以当我运行nosetests 时我没有得到那个错误(即使我也没有将NAME 重命名为foobar)以进一步复杂化它说nosetests 应该只从父目录运行,即skeleton 或foobar,而不是从像 NAME 这样的孩子......但是当我从 name 运行鼻子测试时

drewvcomp/project/foobar/name: >>> nosetests 

它运行得很好。

所以在阅读了很多关于nosetests 并且没有真正看到我应该想办法解决这个问题之后,我只是使用删除了我的整个项目文件夹

rm -rf 项目

并重建它。但没有运气,问题仍然存在。

下面的建议让我觉得也许项目(以及其中的所有内容?)正在被 python 检查。在这种情况下,当我在 foobar 中运行 nosetests 时没问题,因为它能够导入一个名为 NAME 的模块(它存在于原始骨架目录中)。

所以:

导入系统 系统路径 ['', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/projectname-0.1-py2.7.egg', '/ usr/lib/python2.7'、'/usr/lib/python2.7/plat-linux2'、'/usr/lib/python2.7/lib-tk'、'/usr/lib/python2.7/lib -old'、'/usr/lib/python2.7/lib-dynload'、'/usr/local/lib/python2.7/dist-packages'、'/usr/lib/python2.7/dist-packages' , '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages /gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/ dist-packages/ubuntuone-client','/usr/lib/python2.7/dist-packages/ubuntuone-control-panel','/usr/lib/python2.7/dist-packages/ubuntuone-couch',' /usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol', '/var/src/Django-1.3.1 ', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']

哎呀!我需要把它清理干净!除了原来的和 django 之外,我真的不需要太多其他的(我应该在哪里安装?...)

如果你能读完所有这些,如果你能就本章的第 6 步提供一些建议,我会永远爱你:

  • 使用 setup.py 安装并使用 pip 卸载

我的意思是如何...因为

setup install 

给我一​​个 package.egg-info,我不知道那是什么!

【问题讨论】:

    标签: python nose


    【解决方案1】:

    我认为是这样的:

    他试图教两件事。

    1. 可以将文件名为__init__.py 的目录作为模块导入 蟒蛇。
    2. 使用单元测试会警告您错误,因此是一种很好的做法。
    3. 如果您经常做一些事情,您可能想要创建一个模板结构。

    现在在他的示例中,他创建了一个像这样的文件结构:

    skeleton/
             bin/
                 ..
             NAME/
                  __init__.py
                  .. 
             tests/
                   __init__.py
                   .. 
             docs/
                   ..
    

    然后他复制这个模板结构,执行如下操作:

    cp -r skeleton foobar
    

    所以你最终会得到几乎相同的结果:

    foobar/
           bin/
               ..
           NAME/
                __init__.py
                .. 
           tests/
                 __init__.py
                 .. 
           docs/
                ..
    

    现在您仍然有一个名为NAME 的目录和一个可以在python 中导入的__init__.py。所以你的单元测试不会抱怨。

    现在从你所说的我猜,他不仅复制了骨架,还将 NAME 重命名为不同的东西,因为他想将克隆的骨架用于新项目或其他东西。所以他可能有更多类似的东西:

    foobar/
           bin/
               ..
           someothername/
                __init__.py
                .. 
           tests/
                 __init__.py
                 .. 
           docs/
                ..
    

    现在他的unitests 抱怨了,因为他还没有更新他的import 声明。因此它尝试导入NAME,但如您所见,没有目录NAME 包含__init__.py

    所以我想,在现场练习之后,您错过了他将NAME 重命名为somethingelse 的步骤,这就是您以后无法重现它的原因。


    更新:

    使用:

    import sys
    print sys.path
    

    import imp
    print imp.find_module("NAME")
    

    查看您的代码在哪里找到模块“NAME”

    【讨论】:

    • 我也将我的 NAME 文件夹重命名为我的项目名称。但是你让我思考!也许我将项目添加到我的 python/库路径或其他东西。我再看一遍。无论如何感谢您的帮助!
    • 嗯,是的,这可能是我忘记提及的另一种可能性,因为您复制的旧 sekleton/NAME 文件夹仍然存在,如果骨架将是您的 python 路径。你会看到的。
    • 事实上这里有一个方便的提示:python 有一个名为“imp”的模块,使用它来查看你在哪里找到一个模块。进口小鬼; print imp.find_module("NAME");
    【解决方案2】:

    我认为到目前为止问题的最后一部分尚未得到解答:

    如果你能读完所有这些,如果你能就本章的第 6 步提供一些建议,我会永远爱你:

    使用 setup.py 安装并使用 pip 卸载

    stackoverflow 的另一个问题中有一个related answer。我想你的问题的答案在最后。我认为“使用 setup.py 安装”是指:

    python setup.py sdist
    

    然后,如果你的模块被称为 NAME,你运行:

    sudo pip install NAME-0.1.tar.gz   # or a similar filename in the /dist/ directory that is created
    

    要卸载,请运行:

    sudo pip uninstall NAME
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-08
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      相关资源
      最近更新 更多