将python脚本参数传递给测试模块

时间:2011-12-13 21:10:30

标签: python unit-testing

我有几个测试模块都是通过驱动程序脚本一起调用的,它可以采用各种参数。测试本身是使用python unittest模块编写的。

import optparse
import unittest
import sys
import os

from tests import testvalidator
from tests import testmodifier
from tests import testimporter

#modify the path so that the test modules under /tests have access to the project root
sys.path.insert(0, os.path.dirname(__file__))

def run(verbosity):
    if verbosity == "0":
            sys.stdout = open(os.devnull, 'w')

    test_suite = unittest.TestSuite()
    test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(testvalidator.TestValidator))
    test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(testmodifier.TestModifier))
    test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(testimporter.TestDataImporter))

    unittest.TextTestRunner(verbosity=int(verbosity)).run(test_suite)

if __name__ == "__main__":

    #a simple way to control output verbosity
    parser = optparse.OptionParser()
    parser.add_option("--verbosity", "--verbosity", dest="verbosity", default="0")
    (options, args) = parser.parse_args()

    run(options.verbosity)

我的问题是,在这些测试模块中,我有一些我想根据传递给驱动程序的不同参数跳过的测试。我知道unittest提供了一系列装饰器,但我不知道将这些信息传递给各个模块的最佳方法。例如,如果我有一个--skip-slow参数,那么我怎么能将测试注释为缓慢,并将它们跳过?

感谢您的时间。

3 个答案:

答案 0 :(得分:2)

事实上,我自己也在想这个,最后找到了解决方案。

主档......

...
if __name__ == '__main__':
    args = argparser()

    from tests import *

    ...

在测试模块中,只需:

from __main__ import args

print args

我测试了这个,它工作得很好。好的是它是多么简单,而且它根本不是一个黑客。

答案 1 :(得分:1)

您可以使用nose测试运行器和attrib插件,该插件可让您根据属性选择测试用例。特别是,插件文档中的示例使用@attr(slow)来标记慢速测试用例。

之后,从命令行:

  • 选择标记为slow的所有测试用例:

    $ nosetests -a slow

  • 选择未标记为slow的所有测试用例:

    $ nosetests -a '!slow'

答案 2 :(得分:0)

这是我解决此问题的方法。在模块的底部,我根据下面的代码--slow中的argv参数来设置全局变量:

if __name__ == "__main__":
    try:
        i = sys.argv.index("--slow")
        run_slow_tests=True
        del sys.argv[i]
    except ValueError:
        pass

    unittest.main()

然后在运行缓慢的测试功能开始时,我放置了此语句。如果该标志未设置为包括慢速测试,则会引发unittest.SkipTest() exception

if not run_slow_tests:
    raise unittest.SkipTest('Slow test skipped, unless --slow given in sys.argv.')

然后,当我正常调用模块时,将跳过慢速测试。

% python src/my_test.py -v       
test_slow (__main__.Tests) ... skipped 'Slow test skipped, unless --slow given in sys.argv.'

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK (skipped=1)

当我添加--slow时,该模块中的慢速测试将运行:

% python src/my_test.py -v --slow
test_slow (__main__.Tests) ... ok

----------------------------------------------------------------------
Ran 1 test in 10.110s

OK

不幸的是,这不适用于Unittest's test discovery

% python -m unittest discover src "*_test.py" --slow
usage: python -m unittest discover [-h] [-v] [-q] [--locals] [-f] [-c] [-b]
                                   [-k TESTNAMEPATTERNS] [-s START]
                                   [-p PATTERN] [-t TOP]
python -m unittest discover: error: unrecognized arguments: --slow

使用 @ unittest.SkipUnless()装饰器也无效。我怀疑这是因为装饰器会在模块定义时评估其参数,但是直到模块运行时才将参数设置为正确的值。

它不是完美的,但是它使我可以在Python标准库中工作。这样的要求是采用更好的框架(例如nose tests)的充分理由。对于我当前的项目,我希望避免安装任何外部模块。