在nosetests中有条件跳过TestCase装饰器

zii*_*ima 13 python testing nose

有没有办法TestCase使用nosetests基于自定义条件跳过整个?我的意思是unittest.skip*风格.

我试过了

import unittest

@unittest.skip("No reason")
class TestFoo(object):
    def test_foo(self):
        assert False
Run Code Online (Sandbox Code Playgroud)

我发现这个工作使用python <= 2.7.3(显然是偶然的),但在python 2.7.6中没有.

有没有鼻子测试方法,或者我必须创建自己的装饰器?

笔记:

  • 我们尝试了python 2.7.3,2.7.6和nosetests 1.1.2,1.3.0的所有组合.
  • 如果该类继承了unittest.TestCase它的作用,但这不是我需要的.
  • 它似乎在setUpClass加注时起作用SkipTest,但看起来很笨拙.
  • 我找到了nottest装饰器,但它没有将测试标记为跳过.

摘要

  • 更新20. 5. 2014:到目前为止,我还没有找到任何解决这个问题的方法,因此似乎唯一的选择是编写自定义装饰器.
  • 更新12. 6. 2014:我发现养SkipTest在setUpClass不是因为nosetests在某些情况下,一个好主意,不会teardownContext在这些情况下.如果涉及插件,这可能会产生不利影响.

小智 9

我观察到了同样的行为,即使用nose运行我的测试时,unittest.skip,unittest.skipIf等装饰器不受尊重.

Bakuriu建议编写一个在setUpClass方法中引发SkipTest异常的装饰器,这样可以解决问题:无论是从unittest.main还是从nose运行,现在都可以正确跳过测试.

这是代码,主要基于unittest装饰器源代码.关键行是在TestCase类上使用装饰器的时候:

from unittest import SkipTest, TestCase
import functools
import types

def _id(obj):
    return obj

def skip(reason):
    """Unconditionally skip a test."""
    def decorator(test_item):
        if not isinstance(test_item, (type, types.ClassType)):
            @functools.wraps(test_item)
            def skip_wrapper(*args, **kwargs):
                raise SkipTest(reason)
            test_item = skip_wrapper
        elif issubclass(test_item, TestCase):
            @classmethod
            @functools.wraps(test_item.setUpClass)
            def skip_wrapper(*args, **kwargs):
                raise SkipTest(reason)
            test_item.setUpClass = skip_wrapper
        test_item.__unittest_skip__ = True
        test_item.__unittest_skip_why__ = reason
        return test_item
    return decorator

def skipIf(condition, reason):
    """Skip a test if the condition is true."""
    if condition:
        return skip(reason)
    return _id
Run Code Online (Sandbox Code Playgroud)


Mar*_*oma 5

是.

from nose.plugins.skip import SkipTest

@SkipTest
def execute_main_test():
    model_small = os.path.join(utils.get_project_root(),
                               "models",
                               "small-baseline")
    view.main(True, model_small, False, 31, False, 'mysql_online')
    view.main(False, model_small, False, 31, False, 'mysql_online')
    view.main(False, model_small, True, 31, False, 'mysql_online')
    view.main(False, model_small, False, 31, True, 'mysql_online')
Run Code Online (Sandbox Code Playgroud)