带命令行参数的Nose测试脚本

17 投票
5 回答
21033 浏览
提问于 2025-04-15 15:35

我想运行一个可以接受命令行参数的nose测试脚本。比如说,像这样:

test.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做些什么。有没有办法让nose忽略这些参数呢?

5 个回答

7

我觉得这个情况完全可以接受。我之前也需要做类似的事情,以便在不同的环境下(比如开发、测试、生产等)运行测试,这样我就需要为每个环境准备正确的URL和配置。

我找到的解决办法是使用nose-testconfig这个插件(这里有链接)。这并不是直接在命令行中传递参数,而是创建一个配置文件,把所有的参数都放在里面,然后在执行nose测试的时候把这个配置文件作为参数传进去。

这个配置文件的格式如下:

[group1]
env=qa

[urlConfig]
address=http://something

[dbConfig]
user=test
pass=test

你可以通过以下方式读取这些参数:

from testconfig import config

print(config['dbConfig']['user'])
13

你可以用其他方法把东西放进你的代码里:

import os

print os.getenv('KEY_THAT_MIGHT_EXIST', default_value)

然后记得在运行nose之前设置好你的环境。

20

好吧,我和大家一样也不喜欢“你为什么想这么做?”这种回答,但在这里我得说一下。我希望你能理解。

我认为你想做的事情不太符合nose框架的使用范围。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

更新:

我之所以需要这么做,是因为我在测试同一个库的多个实现。为了验证这些实现是否正确,我使用一个单一的nose脚本,它接受一个命令行参数,指定要导入哪个库进行测试。

听起来你可能想尝试写一个nose插件。其实这很简单。这里是最新的文档。

撰写回答