这可能是一个简单的问题;我想在Python测试用例中使用自定义的相等操作符。例如,假设我想测试一个“数字到字符串”函数,并且我想执行一个不区分大小写的字符串比较。
我想写的是:
class MyTest(unittest.TestCase):
def testFoo(self):
self.assertCheck(ci_string_eq,i2s(24),"Twenty-Four")
问题是,assertCheck
不是一件事。
一些明显的解决办法是:
我希望我错过了一些明显的东西?
事先非常感谢!
编辑:有人建议我重写__eq__
。这不是我想要的。具体来说,我的代码的客户端使用__eq__
方法来确定两个对象是否应该被认为是“相同的”(cf )。“扩大平等”)。不过,为了测试的目的,我想使用不同的谓词进行测试。所以覆盖__eq__
并不能解决我的问题。
发布于 2017-03-01 19:31:39
好消息是,没有任何复杂的连接可以使用您自己的规则进行自定义断言。只需进行比较,收集任何有用的信息,然后在需要时调用fail(msg)
。能处理你需要的任何报告。
当然,我太懒了,甚至不喜欢收集有用的信息。我经常发现有用的是从预期数据和实际数据中删除不相关的内容,然后使用常规的assertEquals(expected, actual)
。
下面是这两种技术的一个例子,另外还有一个使用longMessage
来包含上下文的额外技术:
# file scratch.py
from unittest import TestCase
import sys
def convert(i):
results = 'ONE TOO THREE'.split()
return results[i-1]
class FooTest(TestCase):
def assertResultEqual(self, expected, actual):
expected_lower = expected.lower()
actual_lower = actual.lower()
if expected_lower != actual_lower:
self.fail('Results did not match: {!r}, {!r}, comparing {!r}, {!r}'.format(
expected,
actual,
expected_lower,
actual_lower))
def assertLazyResultEqual(self, expected, actual):
self.assertEqual(expected.lower(), actual.lower())
def assertLongLazyResultEqual(self, expected, actual):
self.longMessage = True
self.assertEqual(expected.lower(),
actual.lower(),
'originals: {!r}, {!r}'.format(expected, actual))
def test_good_convert(self):
expected = 'One'
s = convert(1)
self.assertResultEqual(expected, s)
self.assertLazyResultEqual(expected, s)
self.assertLongLazyResultEqual(expected, s)
def test_bad_convert(self):
expected = 'Two'
s = convert(2)
self.assertResultEqual(expected, s)
def test_lazy_bad_convert(self):
expected = 'Two'
s = convert(2)
self.assertLazyResultEqual(expected, s)
def test_long_lazy_bad_convert(self):
expected = 'Two'
s = convert(2)
self.assertLongLazyResultEqual(expected, s)
这将生成以下输出,包括上下文以及传递和失败计数的报告。
$ python -m unittest scratch
F.FF
======================================================================
FAIL: test_bad_convert (scratch.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/don/workspace/scratch/scratch.py", line 43, in test_bad_convert
self.assertResultEqual(expected, s)
File "/home/don/workspace/scratch/scratch.py", line 18, in assertResultEqual
actual_lower))
AssertionError: Results did not match: 'Two', 'TOO', comparing 'two', 'too'
======================================================================
FAIL: test_lazy_bad_convert (scratch.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/don/workspace/scratch/scratch.py", line 50, in test_lazy_bad_convert
self.assertLazyResultEqual(expected, s)
File "/home/don/workspace/scratch/scratch.py", line 21, in assertLazyResultEqual
self.assertEqual(expected.lower(), actual.lower())
AssertionError: 'two' != 'too'
- two
? ^
+ too
? ^
======================================================================
FAIL: test_long_lazy_bad_convert (scratch.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/don/workspace/scratch/scratch.py", line 57, in test_long_lazy_bad_convert
self.assertLongLazyResultEqual(expected, s)
File "/home/don/workspace/scratch/scratch.py", line 27, in assertLongLazyResultEqual
'originals: {!r}, {!r}'.format(expected, actual))
AssertionError: 'two' != 'too'
- two
? ^
+ too
? ^
: originals: 'Two', 'TOO'
----------------------------------------------------------------------
Ran 4 tests in 0.002s
FAILED (failures=3)
如果自定义比较适用于特定类,则可以对该类进行添加自定义相等运算符。如果在setUp()
方法中这样做,那么所有的测试方法都可以使用该类调用assertEquals()
,并且您的自定义比较将被调用。
发布于 2018-09-20 02:16:46
内置的单元测试模块有一个特定的方法,称为addTypeEqualityFunc
。你可以读到它,这里。您只需编写相等的函数并传递它,并像往常一样简单地使用assertEqual
方法。
发布于 2017-02-23 10:31:09
如您所见,没有任何断言需要使用自定义谓词来计算,但是通过msg
参数将自定义错误消息传递给断言方法可以获得更有用的错误消息。
例如:
class MyTest(unittest.TestCase):
def testFoo(self):
self.assertEqual(i2s(24),"Twenty-Four",msg="i2s(24) should be 'Twenty-Four'")
如果这对您来说还不够,那么您就不需要深入研究unittest
:您可以定义一个用所需方法扩展unittest
's TestCase的类,即:
class CustomTestCase(unittest.TestCase):
def assertCheck(self):
...
然后将测试定义为:
class MyTest(CustomTestCase):
def testFoo(self):
self.assertCheck(...)
https://stackoverflow.com/questions/42423350
复制