这可能是一个简单的问题;我想在Python unittest
测试用例中使用自定义相等运算符。例如,假设我想测试一个"数字到字符串"函数,我想执行不区分大小写的字符串比较。
以下是我想写的内容:
class MyTest(unittest.TestCase):
def testFoo(self):
self.assertCheck(ci_string_eq,i2s(24),"Twenty-Four")
问题是assertCheck
不是一件事。
一些明显的解决方法:
我希望我错过了一些明显的东西?
非常感谢提前!
编辑:有人建议我覆盖__eq__
。这不是我想要的。具体来说,我的代码的客户端使用__eq__
方法来确定
是否应该考虑两个对象"相同" (参见"伸展平等")。
但是,出于测试目的,我想使用不同的谓词进行测试。
所以重写__eq__
并不能解决我的问题。
答案 0 :(得分:2)
内置的unittest模块对此具有一种特定的方法,称为addTypeEqualityFunc
。您可以阅读有关here的信息。
您只需要编写相等函数并传递它,然后像往常一样简单地使用assertEqual
方法即可。
答案 1 :(得分:1)
Here's the full list of supported assertions in Python 3.6's unittest
module.
正如您所看到的,没有断言需要自定义谓词来评估,但是您可以通过{{>自定义错误消息将{em>自定义错误消息传递给您的断言方法,从而获得更有用的错误消息1}}论证。
例如:
msg
如果这对你来说还不够,你真的不需要四处寻找class MyTest(unittest.TestCase):
def testFoo(self):
self.assertEqual(i2s(24),"Twenty-Four",msg="i2s(24) should be 'Twenty-Four'")
:你可以用你需要的方法定义一个扩展unittest
的TestCase的类,即:
unittest
然后您将测试定义为:
class CustomTestCase(unittest.TestCase):
def assertCheck(self):
...
答案 2 :(得分:1)
好消息是,没有任何复杂的布线可以使用您自己的规则进行自定义断言。只需进行比较,收集任何有用的信息,然后根据需要调用fail(msg)
。这将照顾您需要的任何报告。
当然,我很懒,我甚至不想收集有用的信息。我经常发现有用的是从预期数据和实际数据中删除不相关的东西,然后使用常规Route::post('/status/{statusId}/reply', [
'uses' => '\CommendMe\Http\Controllers\StatusController@postReply',
'as' => 'status.reply',
'middleware' => ['auth'],
]);
。
以下是两种技术的示例,以及使用longMessage
包含上下文的奖励:
$( ".replyForm" ).submit(function( e ) {
e.preventDefault();
var $token = $('input[name=_token]').val();
var dataString = $(this).serialize();
var $replyValue = $(this).attr('data-value');
$.ajax({
type: "POST",
url: host + '/status/' + $replyValue + '/reply',
data: {replyValue: $replyValue, _token:$token},
success: function(res) {
}
});
});
生成以下输出,包括上下文和通过和失败计数的报告。
assertEquals(expected, actual)
如果自定义比较适用于特定的类,那么您可以为该类add a custom equality operator。如果您在# 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)
,并且将调用您的自定义比较。
答案 3 :(得分:0)
您可以覆盖返回值类的__eq__
方法,而无需通过子类化对原始单元进行卷积。
class Helper(FooReturnValueClass):
def __init__(self, obj=None, **kwargs):
self.obj = obj
# any other attrs
# probably good idea to skip calling super
def __eq__(self, other):
# logic
class MyTest(unittest.TestCase):
def testFoo(self):
expect = self.Helper(...)
actual = ClassUnderTest.foo(...)
self.assertEqual(expect, foo) # Order is important