16

我希望能够运行一个接受命令行参数的鼻子测试脚本。例如,类似的东西:

测试.py

import nose, sys

def test():
    # do something with the command line arguments
    print sys.argv

if __name__ == '__main__':
    nose.runmodule()

但是,每当我使用命令行参数运行它时,都会出现错误:

$ python test.py arg
E
======================================================================
ERROR: Failure: ImportError (No module named arg)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/nose-0.11.1-py2.6.egg/nose/loader.py", line 368, in loadTestsFromName
    module = resolve_name(addr.module)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/nose-0.11.1-py2.6.egg/nose/util.py", line 334, in resolve_name
    module = __import__('.'.join(parts_copy))
ImportError: No module named arg

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

显然,nose 试图对 sys.argv 中传递的参数做一些事情。有没有办法让鼻子忽略这些论点?

4

5 回答 5

18

好吧,我讨厌“你为什么要那样做?” 答案和任何人一样多,但我将不得不在这里做一个。我希望你不要介意。

我认为做任何你想做的事情都不在框架鼻子的范围内。Nose 用于自动化测试。如果您必须传递命令行参数才能通过测试,那么它不是自动化的。现在,你可以做的是这样的:

import sys

class test_something(object):
    def setUp(self):
        sys.argv[1] = 'arg'
        del sys.argv[2] # remember that -s is in sys.argv[2], see below
    def test_method(self):
        print sys.argv

如果你运行它,你会得到这个输出:

[~] nosetests test_something.py -s
['/usr/local/bin/nosetests', 'arg']
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

(如果您想查看标准输出的内容,请记住传入 -s 标志)

但是,我可能仍然建议不要这样做,因为如果可以避免的话,在自动化测试中弄乱全局状态通常是一个坏主意。我可能会做的是调整我想要测试的任何代码来获取argv列表。然后,您可以在测试期间传入任何您想要的内容并sys.argv在生产中传入。

更新

我需要这样做的原因是因为我正在测试同一个库的多个实现。为了测试这些实现是否正确,我使用了一个鼻子脚本,它接受它应该导入用于测试的库作为命令行参数。

听起来您可能想尝试编写一个鼻子插件。这很容易做到。 这是最新的文档。

于 2009-11-02T12:58:25.303 回答
12

您可以使用另一种方法将内容放入您的代码中:

import os

print os.getenv('KEY_THAT_MIGHT_EXIST', default_value)

然后只记得在流鼻涕之前设置你的环境。

于 2013-04-30T00:26:25.140 回答
7

我认为这是一个完全可以接受的情况。为了针对不同的场景(dev、qa、prod 等)运行测试,我还需要做类似的事情,并且我需要为每个环境提供正确的 URL 和配置。

我找到的解决方案是使用nose-testconfig插件(链接在这里)。它不完全是传递命令行参数,而是使用所有参数创建一个配置文件,然后在执行鼻子测试时将此配置文件作为参数传递。

配置文件具有以下格式:

[group1]
env=qa

[urlConfig]
address=http://something

[dbConfig]
user=test
pass=test

您可以使用以下方法阅读参数:

from testconfig import config

print(config['dbConfig']['user'])
于 2015-04-01T08:44:08.633 回答
3

现在我正在使用以下技巧:

args = sys.argv[1:]
sys.argv = sys.argv[0:1]

它只是将参数读入局部变量,然后删除所有附加参数,sys.argv这样鼻子就不会被它们弄糊涂了。

于 2009-11-11T22:09:39.010 回答
2

仅运行鼻子并传入参数将不起作用,因为鼻子会尝试将参数解释为鼻子参数,因此您会遇到所看到的问题。

我不认为直接传递鼻子支持参数但是这个鼻子插件nose-testconfig允许你编写如下测试:

from testconfig import config
def test_os_specific_code():
    os_name = config['os']['type']
    if os_name == 'nt':
        pass # some nt specific tests
    else:
        pass # tests for any other os
于 2009-11-02T12:39:39.440 回答