0

我正在编写一些适用于非常大和非常小的浮点数的代码(例如,1e-150 可能是一个有效的答案)。为了对此进行单元测试,我想将浮点数与一些有效数字而不是小数位进行比较,所以我有以下内容。

import unittest as ut
from numpy.testing import assert_approx_equal

class newTestCase(ut.TestCase):
"""Extends the basic unittest TestCase."""

def assertSFAlmostEqual(self, a, b, places=7):
    """Uses numpy to test if two floats are the same but to a defined
    number of significant figures rather than decimal places.

    Args:
        a: float to be compared
        b: float to be compared
        places: number of significant figures to match. unittest default
        for assertAlmostEqual is 7, so 7 is the default here
    """
    if isinstance(a, float) != True or isinstance(b, float) != True:
        raise TypeError

    raised = False
    try:
        assert_approx_equal(a, b, significant=places)
    except:
        raised = True
    self.assertFalse(raised, "FLoats %g and %g are not equal to %i "
                     "significant figures" % (a, b, places))

这似乎工作正常,但我计划在很多地方使用它,所以我想确定它真的能正常工作。我的问题是我怎样才能最明智地做到这一点?是否有适当的机制来对单元测试进行单元测试?

我在这里找到了可能的答案,

如何对单元测试测试用例进行单元测试

但我不明白这是如何工作的。

首先十分感谢!

4

2 回答 2

2

的子类unittest.TestCase任何其他类一样,因此您可以编写一个unittest.TestCase来检查其方法是否按应有的方式工作。

特别是,您应该构建应该通过和未通过测试的数对集合,然后assertSFAlmostEqual使用这些输入调用方法并查看测试是通过还是失败。

您链接的答案就是这样做的,即使它可能比所需的解决方案更复杂。例如,我只是写了类似的东西:

import unittest


class MyBaseTestCase(unittest.TestCase):
    def assertSpec(self, thing):
        assert thing == 123


class TestMyTest(MyBaseTestCase):
    def test_failures(self):
        self.assertRaises(AssertionError, self.assertSpec, 121)

    def test_successes(self):
        self.assertSpec(123)

if __name__ == "__main__":
    unittest.main()

您只需将测试用例子类化,所有测试只需assert*使用您知道应该通过/不通过测试的特定参数调用您编写的方法。


关于您当前实现该assert*方法的一些注意事项:

if isinstance(a, float) != True or isinstance(b, float) != True:

避免与Trueor比较False。在您的情况下,您可以简单地编写:

if not isinstance(a, float) or not isinstance(b, float):
# or:
if not (isinstance(a, float) and isinstance(b, float))

这也更清楚阅读。

raised = False
try:
    assert_approx_equal(a, b, significant=places)
except:
    raised = True

永远不要使用普通的except:. 在这种情况下,您真的只想捕获AssertionErrorraise by assert_approx_equal,因此您应该使用:

raised = False
try:
    assert_approx_equal(a, b, significant=places)
except AssertionError:
    raised = True

其次,您可以避免使用raised标志。该try-except语句允许else仅在未引发异常时执行的子句:

try:
    assert_approx_equal(a, b, significant=places)
except AssertionError:
    # here put the code to be executed when the assertion fails.
else:
    # here put the code to be executed when *no* exception was raised.
于 2013-09-09T09:35:32.400 回答
0

一种方法是 TDD(测试驱动开发):

  1. 写一个失败的测试。
  2. 使代码通过测试。
  3. 重构。
  4. 转到 1。

这里的关键是首先编写一个失败的测试。

于 2014-01-10T18:24:26.970 回答