unittest-如何断言两个可能的NaN值是否相等

时间:2018-08-07 13:49:20

标签: python nan equality python-unittest

在我的测试案例中,我假设如果两个值是NaN,则它们相等。使用unittest断言来表达它的方式是什么?下面介绍的两个常用功能无法处理这种情况。

v1 = np.nan
v2 = np.nan
self.assertEquals(v1, v2)
self.assertTrue(v1 == v2)

目前对我有用的解决方案是在assertTrue中使用布尔表达式:

self.assertTrue(v1 == v2 or (np.isnan(v1) and np.isnan(v2))

5 个答案:

答案 0 :(得分:6)

您可以使用:

numpy.testing.assert_equal(v1, v2)

来自docs

此函数将NaN比较视为NaN是“正常”数字。 也就是说,如果两个对象在同一位置都具有NaN,则不会引发任何断言 职位。这与NaN的IEEE标准相反,后者 说NaN与任何东西相比都必须返回False。

当值不相等时,它将引发AssertionError,并且在pytest上应该可以正常工作,但可能不适用于单元测试。

另一个选择是:

numpy.isclose(v1, v2, equal_nan=True)

但是很明显,它是math.isclose的替代品,而不是==

答案 1 :(得分:2)

检查两个NaN是否相等没有道理。最好的办法是以另一种方式检查它,例如:

check = numpy.isnan(v1) and numpy.isnan(v2)
self.assertTrue(check)

答案 2 :(得分:1)

检查nan的标准方法是

assert (v1 != v1) and (v2 != v2)

即不等于自身的东西,例如:

>>> n = float('nan')
>>> n != n
True

答案 3 :(得分:0)

您可以分别检查它们是否均为NaN。为此,我建议使用以下类:

import math


class NumericAssertions:
    """
    This class is following the UnitTest naming conventions.
    It is meant to be used along with unittest.TestCase like so :
    class MyTest(unittest.TestCase, NumericAssertions):
        ...
    It needs python >= 2.6
    """

    def assertIsNaN(self, value, msg=None):
        """Fail if provided value is not NaN"""
        standardMsg = "%s is not NaN" % str(value)
        try:
            if not math.isnan(value):
                self.fail(self._formatMessage(msg, standardMsg))
        except:
            self.fail(self._formatMessage(msg, standardMsg))

    def assertIsNotNaN(self, value, msg=None):
        """Fail if provided value is NaN"""
        standardMsg = "Provided value is NaN"
        try:
            if math.isnan(value):
                self.fail(self._formatMessage(msg, standardMsg))
        except:
            pass

这很容易:

v1 = np.nan
v2 = np.nan
self.assertIsNaN(v1)
self.assertIsNaN(v2)

答案 4 :(得分:0)

您可以使用math.isnan

self.assertTrue(math.isnan(v1) and math.isnan(v2))