简体   繁体   English

如何断言 Unittest 上的可迭代对象不为空?

[英]How to assert that an iterable is not empty on Unittest?

After submitting queries to a service, I get a dictionary or a list back and I want to make sure it's not empty.向服务提交查询后,我会得到一本字典或一个列表,我想确保它不是空的。 I using Python 2.7.我使用 Python 2.7。

I am surprised of not having any assertEmpty method for the unittest.TestCase class instance.我很惊讶unittest.TestCase类实例没有任何assertEmpty方法。

The existing alternatives just don't look right:现有的替代方案看起来不正确:

self.assertTrue(bool(d))
self.assertNotEqual(d,{})
self.assertGreater(len(d),0)

Is this kind of a missing method in the Python unittest framework? Python unittest 框架中缺少这种方法吗? If yes, what would be the most pythonic way to assert that an iterable is not empty?如果是,那么断言可迭代对象不为空的最pythonic方法是什么?

空列表/字典评估为 False,因此self.assertTrue(d)完成工作。

Depends exactly what you are looking for.取决于你正在寻找什么。

If you want to make sure the object is an iterable and it is not empty:如果要确保对象是可迭代的并且不为空:

# TypeError: object of type 'NoneType' has no len()
# if my_iterable is None
self.assertTrue(len(my_iterable))

If it is OK for the object being tested to be None :如果被测试的对象可以为None

self.assertTrue(my_maybe_iterable)

"Falsy" values in Python Python 中的“假”值

A falsy (sometimes written falsey) value is a value that is considered false when encountered in a Boolean context.假(有时写成假)值是在布尔上下文中遇到时被认为是假的值。

According to the official doc , the following built-in types evaluate to false:根据官方文档,以下内置类型评估为假:

  • constants defined to be false: None and False .定义为 false 的常量: NoneFalse
  • zero of any numeric type: 0 , 0.0 , 0j , Decimal(0) , Fraction(0, 1)任何数字类型的零: 0 , 0.0 , 0j , Decimal(0) , Fraction(0, 1)
  • empty sequences and collections: '' , () , [] , {} , set() , range(0)空序列和集合: '' , () , [] , {} , set() , range(0)

Therefore, it's possible to check for因此,可以检查

(The official doc has a full list of all available assert methods .) (官方文档有所有可用 断言方法的完整列表。)

Clean Code干净的代码

All those assertTrue() and assertFalse() calls are kind of misleading as we wanted to check for emptiness and one needs to know which types evaluate to false to properly understand what's happening in the test.所有这些assertTrue()assertFalse()调用都具有误导性,因为我们想要检查是否为空,并且需要知道哪些类型评估为false以正确理解测试中发生的情况。

So, for the sake of clean code and for better readability, we can simply define our own assertEmpty() and assertNotEmpty() methods like so:因此,为了代码简洁和可读性更好,我们可以简单地定义我们自己的assertEmpty()assertNotEmpty()方法,如下所示:

def assertEmpty(self, obj):
    self.assertFalse(obj)

def assertNotEmpty(self, obj):
    self.assertTrue(obj)

也许:

self.assertRaises(StopIteration, next(iterable_object))

All the credit for this goes to winklerrr, I am just extending his idea: have importable mixins for when you need assertEmpty or assertNotEmpty:这一切都归功于 winklerrr,我只是扩展了他的想法:在需要 assertEmpty 或 assertNotEmpty 时使用可导入的 mixin:

class AssertEmptyMixin( object ):
    def assertEmpty(self, obj):
        self.assertFalse(obj)

class AssertNotEmptyMixin( object ):
    def assertNotEmpty(self, obj):
        self.assertTrue(obj)

Caveat, mixins should go on the left:注意,mixin 应该放在左边:

class MyThoroughTests( AssertNotEmptyMixin, TestCase ):
    def test_my_code( self ):
        ...
        self.assertNotEmpty( something )

Based on @winklerr's answer and @Merk's comment, I extended the idea for checking whether the given object is a Container in the first place.根据@winklerr 的回答和@Merk 的评论,我扩展了首先检查给定对象是否为Container的想法。

from typing import Container


def assertContainerEmpty(self, obj: Container) -> None:
    """Asserts whether the given object is an empty container."""
    self.assertIsInstance(obj, Container)
    self.assertFalse(obj)

def assertContainerNotEmpty(self, obj: Container) -> None:
    """Asserts whether the given object is a non-empty container."""
    self.assertIsInstance(obj, Container)
    self.assertTrue(obj)

This means that assertEmpty and assertNotEmpty will always fail if the given object is eg a float , or an instance of an user-defined class - no matter if it would properly evaluate to True / False .这意味着如果给定的对象是float或用户定义的类的实例, assertEmptyassertNotEmpty将始终失败 - 无论它是否正确评估为True / False

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

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