首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python :如何指定自定义相等谓词?

Python :如何指定自定义相等谓词?
EN

Stack Overflow用户
提问于 2017-02-23 10:20:35
回答 4查看 3.4K关注 0票数 6

这可能是一个简单的问题;我想在Python测试用例中使用自定义的相等操作符。例如,假设我想测试一个“数字到字符串”函数,并且我想执行一个不区分大小写的字符串比较。

我想写的是:

代码语言:javascript
运行
AI代码解释
复制
class MyTest(unittest.TestCase):
    def testFoo(self):
        self.assertCheck(ci_string_eq,i2s(24),"Twenty-Four")

问题是,assertCheck不是一件事。

一些明显的解决办法是:

  • 使用assertTrue;问题是这样一个测试用例失败就变得不透明和毫无帮助;“预期的真,得到了假”。布利亚。
  • 深入研究统一,自己扩展;我希望避免这种情况:)

我希望我错过了一些明显的东西?

事先非常感谢!

编辑:有人建议我重写__eq__。这不是我想要的。具体来说,我的代码的客户端使用__eq__方法来确定两个对象是否应该被认为是“相同的”(cf )。“扩大平等”)。不过,为了测试的目的,我想使用不同的谓词进行测试。所以覆盖__eq__并不能解决我的问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-01 19:31:39

好消息是,没有任何复杂的连接可以使用您自己的规则进行自定义断言。只需进行比较,收集任何有用的信息,然后在需要时调用fail(msg)。能处理你需要的任何报告。

当然,我太懒了,甚至不喜欢收集有用的信息。我经常发现有用的是从预期数据和实际数据中删除不相关的内容,然后使用常规的assertEquals(expected, actual)

下面是这两种技术的一个例子,另外还有一个使用longMessage来包含上下文的额外技术:

代码语言:javascript
运行
AI代码解释
复制
# 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)

这将生成以下输出,包括上下文以及传递和失败计数的报告。

代码语言:javascript
运行
AI代码解释
复制
$ 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(),并且您的自定义比较将被调用。

票数 3
EN

Stack Overflow用户

发布于 2018-09-20 02:16:46

内置的单元测试模块有一个特定的方法,称为addTypeEqualityFunc。你可以读到它,这里。您只需编写相等的函数并传递它,并像往常一样简单地使用assertEqual方法。

票数 3
EN

Stack Overflow用户

发布于 2017-02-23 10:31:09

模块。

如您所见,没有任何断言需要使用自定义谓词来计算,但是通过msg参数将自定义错误消息传递给断言方法可以获得更有用的错误消息。

例如:

代码语言:javascript
运行
AI代码解释
复制
class MyTest(unittest.TestCase):
  def testFoo(self):
    self.assertEqual(i2s(24),"Twenty-Four",msg="i2s(24) should be 'Twenty-Four'")

如果这对您来说还不够,那么您就不需要深入研究unittest:您可以定义一个用所需方法扩展unittest's TestCase的类,即:

代码语言:javascript
运行
AI代码解释
复制
class CustomTestCase(unittest.TestCase):
  def assertCheck(self):
    ...

然后将测试定义为:

代码语言:javascript
运行
AI代码解释
复制
class MyTest(CustomTestCase):
  def testFoo(self):
    self.assertCheck(...)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42423350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档