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

问题描述 投票:0回答:6

在我的测试用例中,我假设如果两个值是

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))
python nan equality python-unittest
6个回答
15
投票

您可以使用:

numpy.testing.assert_equal(v1, v2)

来自文档

此函数处理 NaN 比较,就好像 NaN 是“正常”数字一样。 也就是说,如果两个对象在同一个对象中都具有 NaN,则不会引发断言 职位。这与 NaN 的 IEEE 标准形成鲜明对比,该标准 表示 NaN 与任何内容相比都必须返回 False。

当值不相等时,它会抛出 AssertionError ,并且它应该可以与 pytest 一起正常工作,但它可能不太适合单元测试测试。

另一种选择是:

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

但显然它是

math.isclose
的替代品,而不是
==


5
投票

检查两个 NaN 是否相等是没有意义的。您能做的最好的事情就是以不同的方式检查它,例如:

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

3
投票

您可以使用math.isnan

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

1
投票

您可以分别检查它们是否为 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)

1
投票

检查

nan
s 的标准方法是

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

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

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

0
投票

为了比较可能包含 NaN 值的 Python 数据结构(例如与assertListEqual/assertDictEqual),可以使用以下表达式代替 NaN 常量:

pytest.approx(np.nan, nan_ok=True)
© www.soinside.com 2019 - 2024. All rights reserved.