如何访问unittest.TestCase中的unittest.main(verbosity)设置

时间:2012-12-07 10:57:20

标签: python unit-testing

根据文档,我可以在调用unittest.main时设置python unittest的详细级别,例如

unittest.main(verbosity=2)

如何在unittest.TestCase

中访问此信息

7 个答案:

答案 0 :(得分:5)

基于修补或子类化unittest.TestProgram的任何方法的问题在于,您必须在启动unittest.TestProgram之前获得补丁。但是,如果您的测试用例是通过发现运行的话,这是不可能的:

python -m unittest discover -v

在发现案例中有效的方法是使用inspect模块搜索堆栈,直到找到unittest.TestProgram上的方法:

import inspect
import unittest

def unittest_verbosity():
    """Return the verbosity setting of the currently running unittest
    program, or 0 if none is running.

    """
    frame = inspect.currentframe()
    while frame:
        self = frame.f_locals.get('self')
        if isinstance(self, unittest.TestProgram):
            return self.verbosity
        frame = frame.f_back
    return 0

答案 1 :(得分:3)

实现此目的的一种方法是在文件中继承unittest.TestCaseunittest.main。在这里,您可以定义一个变量(例如globalverb),可以全局使用,也可以作为类或Singleton使用,然后覆盖unittest.main

def main(*args, **kwargs):

    # parse arguments etc to get the verbosity number or whatever
    # ...
    # set this number to the defined class
    globalverb = verbose_number
    return unittest.main(*args, **kwargs)

稍后,您继承unittest.TestCase

class MyTestCase(unittest.TestCase):
    def my_special_function(self):
        if globalverb ...

使用这种方法,可以在传递给unittest的参数中使用(派生的)TestCase中的详细,详细程度或任何其他数字和信息。

欢迎评论。

答案 2 :(得分:2)

我无法让Martjin Pieters的解决方案工作,我认为因为unittest.main在初始化时运行测试,然后将结果分配给全局。

相反,我用:

替换了我的初始化
    def new_parseArgs(self, argv):
        global old_parseArgs,verbosity
        old_parseArgs(self, argv)
        verbosity = self.verbosity

    if __name__ == '__main__':
        # monkeypatch unittest.TestProgram.parseArgs() to save verbosity
        # in a global variable
        old_parseArgs = unittest.TestProgram.parseArgs
        unittest.TestProgram.parseArgs = new_parseArgs

        unittest.main()

在需要了解详细程度的测试用例中,我使用了类似的东西:

            global verbosity

    ...

            if verbosity >= 2:
                print("Keys' order: %s" % dd.keys())

答案 3 :(得分:1)

如果您只想访问-v选项,可以在测试中使用self._resultForDoCleanups.showAll进行检查(继承自unittest.TestCase)。如果为该测试调用-v,则该字段为true。

答案 4 :(得分:0)

我的解决方案完全不同。我没有使用monkeypatching,而是通过特制的启动脚本触发了所有测试。它收集了各种配置变量和设置环境,因此只需添加一个额外的导出即可。

对于更通用的情况,它可能是明智的解决方案,而不是直接运行测试,创建test-runner.sh(或其他),它将完全相同的shell调用,但额外的导出前缀为它。

因为一张图片值得数千字:

这是我的试运行员:

#!/usr/bin/env bash

VERBOSE=false

while getopts ":vt:" opt; do
    case $opt in
        t)
            TEST_TO_RUN=$OPTARG
            ;;
        v)
            VERBOSE=true
            ;;
        \?)
          echo "Invalid option: -$OPTARG" >&2
          exit 1
          ;;
        :)
          echo "Option -$OPTARG requires an argument." >&2
          exit 1
      ;;
    esac
done

ENVS=""
ENVS+=" PYTHONPATH=$PYTHONPATH:$PWD"

PARAMS=""
PARAMS+=" -s --nologcapture --with-id"
PARAMS+=" --cov-config=.apirc --cov-report html --with-cov"

SERVER_PRIMER="coverage run --rcfile=.apirc"

if [[ ! -z "$TEST_TO_RUN" ]]; then
    PARAMS+=" $TEST_TO_RUN"
fi

if [[ "$VERBOSE" = true ]]; then
    PARAMS+=" -v"
    ENVS+=" TEST_VERBOSITY=2"
fi

eval "$ENVS nosetests $PARAMS"

RESULT_TEST=$?

然后我在单元测试中使用了这种方法:

@property
def verbosity(self):
    return int(os.environ.get('TEST_VERBOSITY', 0))

答案 5 :(得分:0)

爬上堆栈,找到unittest.main()创建的“TestProgram”实例,并访问详细程度字段:

class MyTestCase(unittest.TestCase):

    def test_verbosity(self):
        """Return current verbosity"""
        for f in inspect.getouterframes(inspect.currentframe() ):
            args, _,_, local_dict = inspect.getargvalues(f[0])
            if args: 
                first_arg = args[0] 
                first_value = local_dict[first_arg]
                if type(first_value).__name__ == "TestProgram":
                    return first_value.verbosity

答案 6 :(得分:0)

如果您始终从命令行运行,则只需解析sys.argv中的参数即可。您可以手动执行此操作(在列表中查找“ -v”,“-vv”等的出现),但是我通常更喜欢在源代码中查找相关的解析器,并使用相同的版本(带有伪代码)选项被删除)。您的情况如下所示:

相关代码似乎为here。我们可以提取出一部分代码并获得以下信息:

    import argparse


    verbosity_parser = argparse.ArgumentParser(add_help=False)
    verbosity_parser.add_argument(
        '-v', '--verbose', dest='verbosity', 
        action='store_const', const=2,
        help='Verbose output')  # We could remove this if we want
    args, rest = verbosity_parser.parse_known_args()
    verbosity = args.verbosity

编辑

我刚刚意识到解析器有多简单。我习惯了Django,那里有多个详细级别。在这种情况下,您可能只需检查{'-v', '--verbose'} & set(sys.argv)还是类似的内容。

如果您还想处理--quiet标志,则只需使用add_argument方法(同样基于源代码)向argparse添加另一个调用即可。

    parser.add_argument('-q', '--quiet', dest='verbosity',
                        action='store_const', const=0,
                        help='Quiet output')  # this could be removed

如果需要,我们还可以处理似乎是隐式默认值的内容:

    if verbosity is None:
        verbosity = 1