代码之家  ›  专栏  ›  技术社区  ›  Arun

如何在没有太多负担的情况下使用“assertEqual()`[或等效物]?

  •  2
  • Arun  · 技术社区  · 6 年前

    我正在寻找一种方法(如果可用),它可以比较两个值,并在比较失败时用有意义的消息引发断言错误。

    assert ,失败消息不包含在断言失败时比较的值。

    >>> a = 3
    >>> b = 4
    >>> assert a == b
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AssertionError
    >>> 
    

    如果我使用 assertEqual() 方法从 unittest.TestCase 包中,断言消息包含已比较的值。

            a = 3
            b = 4
    >       self.assertEqual(a, b)
    E       AssertionError: 3 != 4
    

    注意,这里的断言错误消息包含比较的值。这在现实生活中非常有用,因此对我来说是必要的。平原 断言 (见上文)不这样做。

    仅在继承自的类中 unittest.TestCase测试用例 并提供了一些其他必需的方法,如 runTest() . 我想用 资产质量() 任何地方,不仅仅是继承类。有可能吗?

    我试过以下方法,但都不管用。

    >>> import unittest
    >>> unittest.TestCase.assertEqual(a, b)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unbound method failUnlessEqual() must be called with TestCase instance as first argument (got int instance instead)
    >>> 
    >>> 
    >>> tc = unittest.TestCase()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib64/python2.6/unittest.py", line 215, in __init__
        (self.__class__, methodName)
    ValueError: no such test method in <class 'unittest.TestCase'>: runTest
    >>> 
    

    资产质量()

    4 回复  |  直到 6 年前
        1
  •  2
  •   Elisha    6 年前

    AssertsAccessor 在这种情况下:

    from unittest import TestCase
    
    # Dummy TestCase instance, so we can initialize an instance
    # and access the assert instance methods
    class DummyTestCase(TestCase):
        def __init__(self):
            super(DummyTestCase, self).__init__('_dummy')
    
        def _dummy(self):
            pass
    
    # A metaclass that makes __getattr__ static
    class AssertsAccessorType(type):
        dummy = DummyTestCase()
    
        def __getattr__(cls, key):
            return getattr(AssertsAccessor.dummy, key)
    
    # The actual accessor, a static class, that redirect the asserts
    class AssertsAccessor(object):
        __metaclass__ = AssertsAccessorType
    

    只需创建一次模块,然后再创建所有模块 资产 unittest 包装可接近,例如:

    AssertsAccessor.assertEquals(1, 2)
    

    断言错误:1!=2

    AssertsAccessor.assertGreater(1, 2)
    

    结果是:

    断言错误:1不大于2

    假设为访问器创建的模块名为 assertions ,代码中的常见用法如下所示:

    from assertions import AssertsAccessor
    
    def foo(small_arg, big_arg):
        AssertsAccessor.assertGreater(big_arg, small_arg)
        # some logic here
    
        2
  •  4
  •   Daniel    6 年前

    assert a == b, '%s != %s' % (a, b)
    # AssertionError: 3 != 4
    
        3
  •  1
  •   Christian Sloper    6 年前

    你看过numpy.testing吗?

    https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.testing.html

    断言几乎相等(实际,期望[,…])如果两个项不等于期望的精度,则引发断言错误。

    这个断言打印出实际的和期望的。如果提高精度,则比较任意接近==(对于浮点)

        4
  •  1
  •   Dluzak    6 年前

    我以前也做过类似的事情,最后写了一个简短的自定义断言,接受任何条件作为输入。

    import inspect
    
    def custom_assert(condition):
        if not condition:
            frame = inspect.currentframe()
            frame = inspect.getouterframes(frame)[1]
            call_signature = inspect.getframeinfo(frame[0]).code_context[0].strip()
    
            import re
            argument = re.search('\((.+)\)', call_signature).group(1)
            if '!=' in argument:
                argument = argument.replace('!=','==')
            elif '==' in argument:
                argument = argument.replace('==','!=')
            elif '<' in argument:
                argument = argument.replace('<','>=')
            elif '>' in argument:
                argument = argument.replace('>','<=')
            elif '>=' in argument:
                argument = argument.replace('>=','<')
            elif '<=' in argument:
                argument = argument.replace('<=','>')
    
            raise AssertionError(argument)
    
    if __name__ == '__main__':
        custom_assert(2 == 1)
    

    Traceback (most recent call last):
      File "custom_assert.py", line 27, in <module>
        custom_assert(2 == 1)
      File "custom_assert.py", line 24, in custom_assert
        raise AssertionError(argument)
    AssertionError: 2 != 1
    
        5
  •  0
  •   Vivek Puurkayastha    6 年前

    assertEqual或任何其他assertXxx()方法要求第一个参数是对象引用。通常我们称这个方法为 self.assertEqual(first, second, msg=None) . 在这里 self 满足第一个预期参数。为了避免这种情况,我们可以采取以下措施:

    from unittest import TestCase as tc
    def some_func():
        dummy_obj = tc()
        tc.assertEqual(dummy_obj, 123, 123, msg='Not Equal')
    

    这种行为的原因是XUnit框架的遗留问题。