我正在编写一些适用于非常大和非常小的浮点数的代码(例如,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))
这似乎工作正常,但我打算在很多地方使用它,所以我想确定它确实可以正常工作。我的问题是我怎样才能最明智地做到这一点?是否有适当的机制来对单元测试进行单元测试?
我在这里找到了可能的答案,
How to unittest unittest TestCases
但我不明白这是如何运作的。
非常感谢!
答案 0 :(得分: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:
避免与True
或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:
捕获异常。在这种情况下,您确实只想捕获AssertionError
引发的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.
答案 1 :(得分:0)
一种方法是TDD(测试驱动开发):
这里的关键是先写一个失败的测试。