【问题标题】:Python/Django: how to assert that unit test result contains a certain string?Python/Django:如何断言单元测试结果包含某个字符串?
【发布时间】:2013-07-06 09:24:39
【问题描述】:

在 python 单元测试(实际上是 Django)中,正确的 assert 语句会告诉我我的测试结果是否包含我选择的字符串?

self.assertContainsTheString(result, {"car" : ["toyota","honda"]})

我想确保我的result 至少包含我指定为上面第二个参数的 json 对象(或字符串)

{"car" : ["toyota","honda"]}

【问题讨论】:

标签: python json django unit-testing assert


【解决方案1】:

要断言一个字符串是否是另一个字符串的子字符串,您应该使用assertInassertNotIn

# Passes
self.assertIn('bcd', 'abcde')

# AssertionError: 'bcd' unexpectedly found in 'abcde'
self.assertNotIn('bcd', 'abcde')

这些是自 Python 2.7Python 3.1 以来的新功能

【讨论】:

  • 另外,assertIn 提供有关失败的有用信息,如您所说明的那样。
【解决方案2】:
self.assertContains(result, "abcd")

您可以修改它以使用 json。

仅将self.assertContains 用于HttpResponse 对象。对于其他对象,请使用self.assertIn

【讨论】:

  • 是的,但是由于 json 结构,它可能会添加一些空格,这在 json 中没有问题,但如果您想与 python 字符串进行比较,则会出现问题。
  • assertContains 不打算用于 HttpReponse 以外的其他对象,而是更喜欢使用带有“in”python 关键字的 assertTrue(请参阅下面的我的答案)。
  • 这是错误的。 Assertconains 用于 http 响应。
  • 这个答案应该澄清它是为 HttpResponse 量身定制的
【解决方案3】:

您可以在另一个字符串中使用简单的 assertTrue + in python 关键字编写关于字符串预期部分的断言:

self.assertTrue("expected_part_of_string" in my_longer_string)

【讨论】:

  • 这个策略的问题是它会给出“AssertionError: False is not true”形式的糟糕失败消息
  • @jamesc 同意你的观点,测试应该显示错误详细信息,如果使用 assertTrue,有什么解决方法?
  • @LukAron 如果你必须使用assertTrue,那么你可以传递一个你预先构建的包含更多细节的消息:assertTrue(expr, msg=message)。如果消息变得复杂,那么您可以将消息构建和 assertTrue 检查提取到单独的断言助手中,该助手可能有自己的测试以确保其行为符合预期。
【解决方案4】:

使用json.dumps() 构建一个 JSON 对象。

然后使用assertEqual(result, your_json_dict)比较它们

import json

expected_dict = {"car":["toyota", "honda"]}
expected_dict_json = json.dumps(expected_dict)

self.assertEqual(result, expected_dict_json)

【讨论】:

  • 为什么使用assertTrue() 而不是assertEqual()?至少使用assertEqual(),模块将打印结果和预期值。
  • 你说得对,assertEqual() 更好。我找不到链接,但我很确定在某处阅读过使用 assertTrue 而不是 assertEqual。显然,我错了:)我会修正上面的例子。
  • 请注意,当您在任何字典中有多个键时,这将是不可靠的,因为dumps() 使用任意顺序并且我们不知道result 中键的顺序。使用self.assertEqual(json.loads(result), expected_dict) 会更好。
【解决方案5】:

As mentioned by Ed I, assertIn 可能是在另一个字符串中查找一个字符串的最简单答案。但是,问题指出:

我想确保我的result 至少包含我指定为上面第二个参数的 json 对象(或字符串),即{"car" : ["toyota","honda"]}

因此,我将使用多个断言,以便在失败时收到有用的消息 - 将来必须理解和维护测试,可能由最初没有编写它们的人来理解和维护。因此假设我们在django.test.TestCase

# Check that `car` is a key in `result`
self.assertIn('car', result)
# Compare the `car` to what's expected (assuming that order matters)
self.assertEqual(result['car'], ['toyota', 'honda'])

提供如下有用信息:

# If 'car' isn't in the result:
AssertionError: 'car' not found in {'context': ..., 'etc':... }
# If 'car' entry doesn't match:
AssertionError: Lists differ: ['toyota', 'honda'] != ['honda', 'volvo']

First differing element 0:
toyota
honda

- ['toyota', 'honda']
+ ['honda', 'volvo']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多