简体   繁体   English

禁用Python测试

[英]Disabling Python nosetests

When using nosetests for Python it is possible to disable a unit test by setting the test function's __test__ attribute to false. 使用Python的nosetests时,可以通过将test函数的__test__属性设置为false来禁用单元测试。 I have implemented this using the following decorator: 我使用以下装饰器实现了这个:

def unit_test_disabled():
    def wrapper(func):
         func.__test__ = False
         return func

    return wrapper

@unit_test_disabled
def test_my_sample_test()
    #code here ...

However, this has the side effect of calling wrapper as the unit test. 但是,这会产生调用包装器作为单元测试的副作用。 Wrapper will always pass but it is included in nosetests output. 包装将始终通过,但它包含在nosetests输出中。 Is there another way of structuring the decorator so that the test will not run and does not appear in nosetests output. 是否有另一种构造装饰器的方法,以便测试不会运行并且不会出现在nosetests输出中。

Nose already has a builtin decorator for this: Nose已经有了一个内置装饰器:

from nose.tools import nottest

@nottest
def test_my_sample_test()
    #code here ...

Also check out the other goodies that nose provides: https://nose.readthedocs.org/en/latest/testing_tools.html 另请查看鼻子提供的其他好东西: https//nose.readthedocs.org/en/latest/testing_tools.html

You can also use unittest.skip decorator: 你也可以使用unittest.skip装饰器:

import unittest


@unittest.skip("temporarily disabled")
class MyTestCase(unittest.TestCase):
    ...

There also is a skiptest plugin for nosetest, which will cause the test show in test output as skipped. 还有一个用于nosetest的skiptest插件,它会导致测试输出中的测试显示被跳过。 Here is a decorator for that: 这是一个装饰器:

def skipped(func):
    from nose.plugins.skip import SkipTest
    def _():
        raise SkipTest("Test %s is skipped" % func.__name__)
    _.__name__ = func.__name__
    return _

Example output: 示例输出:

$ nosetests tests
..........................................................................
..................................S.............
----------------------------------------------------------------------
Ran 122 tests in 2.160s

OK (SKIP=1)

You can just start the class, method or function name with an underscore and nose will ignore it. 您可以使用下划线启动类,方法或函数名称,而nose将忽略它。

@nottest has its uses but I find that it does not work well when classes derive from one another and some base classes must be ignored by nose. @nottest有它的用途,但是我发现当类从彼此派生并且必须被nose忽略一些基类时,它不能很好地工作。 This happens often when I have a series of similar Django views to test. 当我有一系列类似的Django视图进行测试时,通常会发生这种情况。 They often share characteristics that need testing. 它们通常具有需要测试的特征。 For instance, they are accessible only to users with certain permissions. 例如,只有具有特定权限的用户才能访问它们。 Rather than write the same permission check for all of them, I put such shared test in an initial class from which the other classes derive. 我将这种共享测试放在其他类派生的初始类中,而不是对所有这些进行相同的权限检查。 The problem though is that the base class is there only to be derived by the later classes and is not meant to be run on its own. 但问题是基类只是由后面的类派生而不是自己运行。 Here's an example of the problem: 这是一个问题的例子:

from unittest import TestCase

class Base(TestCase):

    def test_something(self):
        print "Testing something in " + self.__class__.__name__

class Derived(Base):

    def test_something_else(self):
        print "Testing something else in " + self.__class__.__name__

And the output from running nose on it: 从鼻子上输出的输出:

$ nosetests test.py -s
Testing something in Base
.Testing something in Derived
.Testing something else in Derived
.
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

The Base class is included in the tests. Base类包含在测试中。

I cannot just slap @nottest on Base because it will mark the entire hierarchy. 我不能仅仅在Base @nottest ,因为它将标记整个层次结构。 Indeed if you just add @nottest to the code above in front of class Base , then nose won't run any tests. 实际上,如果你只是将@nottest添加到class Base前面的代码中,那么nose将不会运行任何测试。

What I do is add an underscore in front of the base class: 我所做的是在基类前面添加一个下划线:

from unittest import TestCase

class _Base(TestCase):

    def test_something(self):
        print "Testing something in " + self.__class__.__name__

class Derived(_Base):

    def test_something_else(self):
        print "Testing something else in " + self.__class__.__name__

And when running it _Base is ignored: 运行时_Base被忽略:

$ nosetests test3.py -s
Testing something in Derived
.Testing something else in Derived
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

This behavior is not well documented but the code that selects tests explicitly checks for an underscore at the start of class names . 此行为没有很好地记录,但选择测试的代码显式检查类名开头的下划线

A similar test is performed by nose on function and method names so it is possible to exclude them by adding an underscore at the start of the name. 类似的测试由函数和方法名称执行,因此可以通过在名称的开头添加下划线来排除它们。

I think you will also need to rename your decorator to something that has not got test in. The below only fails on the second test for me and the first does not show up in the test suite. 我想你还需要将你的装饰器重命名为尚未测试的东西。以下只有在我的第二次测试时失败,第一次没有出现在测试套件中。

def unit_disabled(func):
    def wrapper(func):
         func.__test__ = False
         return func

    return wrapper

@unit_disabled
def test_my_sample_test():
    assert 1 <> 1

def test2_my_sample_test():
    assert 1 <> 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM