【问题标题】:nose plugin for expected-failures预期失败的鼻子插件
【发布时间】:2012-03-08 06:52:37
【问题描述】:

是否有现成的插件可以像这样使用:

@nose.plugins.expectedfailure
def not_done_yet():
    a = Thingamajig().fancynewthing()
    assert a == "example"

如果测试失败,它看起来就像一个跳过的测试:

$ nosetests
...S..

..但如果它意外通过,它看起来类似于失败,可能像:

=================================
UNEXPECTED PASS: not_done_yet
---------------------------------
-- >> begin captured stdout << --
Things and etc
...

类似于like SkipTest,但没有实现为阻止测试运行的异常。

我唯一能找到的是 this ticket 关于支持 unittest2 expectedFailure 装饰器(虽然我宁愿不使用 unittest2,即使鼻子支持它)

【问题讨论】:

    标签: python testing nose


    【解决方案1】:

    我不知道鼻子插件,但您可以轻松编写自己的装饰器来做到这一点。这是一个简单的实现:

    import functools
    import nose
    
    def expected_failure(test):
        @functools.wraps(test)
        def inner(*args, **kwargs):
            try:
                test(*args, **kwargs)
            except Exception:
                raise nose.SkipTest
            else:
                raise AssertionError('Failure expected')
        return inner
    

    如果我运行这些测试:

    @expected_failure
    def test_not_implemented():
        assert False
    
    @expected_failure
    def test_unexpected_success():
        assert True
    

    我从鼻子得到以下输出:

    tests.test.test_not_implemented ... SKIP
    tests.test.test_unexpected_success ... FAIL
    
    ======================================================================
    FAIL: tests.test.test_unexpected_success
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "C:\Python32\lib\site-packages\nose-1.1.2-py3.2.egg\nose\case.py", line 198, in runTest
        self.test(*self.arg)
      File "G:\Projects\Programming\dt-tools\new-sanbi\tests\test.py", line 16, in inner
        raise AssertionError('Failure expected')
    AssertionError: Failure expected
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.016s
    
    FAILED (failures=1)
    

    【讨论】:

    • 哦,当然!稍作调整,以便在测试失败时引发 SkipTest,这非常完美 - 感谢 \o/
    【解决方案2】:

    如果我误解了,请原谅我,但核心 python 的 unittest 库和 expectedFailure 装饰器提供的行为不是您想要的吗?通过扩展,它与 nose 兼容?

    有关使用示例,请参阅 docs 和 post about its implementation。

    【讨论】:

    • 是的,这是真的,但我喜欢鼻子的一件事是能够将测试编写为函数,而不是内置 unittest 模块所要求的子类上的方法(例如 def test_exampleblah(): pass)
    • 如果这就是问题所在,那么您可能会喜欢pytest,即compatible with nose,也支持tests as functions 并具有xfail 装饰器。
    • 根据我的经验,unittest.expectedFailure 与 Nose 不兼容。 Nose bug 33 同意。
    • “与鼻子不兼容”。在 2018 年,对我来说似乎足够兼容。
    【解决方案3】:

    您可以通过以下两种方式之一来实现:

    1. nose.tools.raises装饰器

      from nose.tools import raises
      
      @raises(TypeError)
      def test_raises_type_error():
          raise TypeError("This test passes")
      
    2. nose.tools.assert_raises

      from nose.tools import assert_raises
      
      def test_raises_type_error():
          with assert_raises(TypeError):
              raise TypeError("This test passes")
      

    如果没有引发异常,测试将失败。

    是的,我知道,3 年前问过 :)

    【讨论】:

    • 为什么这被否决了? AFAICT 这是最好的答案。
    猜你喜欢
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多