Python / Django:如何断言单元测试结果包含某个字符串?


78

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

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

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

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

Answers:


64
self.assertContains(result, "abcd")

您可以修改它以使用json。

使用self.assertContains只为HttpResponse对象。对于其他对象,请使用self.assertIn


2
是的,但是由于json结构,它可能添加了一些空格,这些空格在json中不是问题,但是如果要与python字符串进行比较则是有问题的。
弗朗索瓦

32
assertContains不能用于HttpReponse以外的其他对象,而应该使用带有“ in” python关键字的assertTrue来代替(请参见下面的我的答案)。
Pierre Criulanscy

12
错了 Assertconains用于http响应。
kagronick '16

3
该答案应阐明它仅针对HttpResponse量身定制
rtindru

121

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

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

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

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


5
assertIn正如您所说明的,还提供有关故障的有用消息。
jamesc

22

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

self.assertTrue("expected_part_of_string" in my_longer_string)

9
此策略的问题在于,它会以“ AssertionError:False is not true”的形式给出错误的失败消息
jamesc

1
@jamesc同意您的观点,测试应该显示错误详细信息,如果使用assertTrue可以解决此问题吗?
卢克·阿隆

@LukAron如果必须使用assertTrue,则可以传递一条预先构建的消息以包含更多详细信息:assertTrue(expr,msg = message)。如果消息变得复杂,则可以将消息构建和assertTrue检查提取到单独的断言帮助器中,该帮助器可能具有自己的测试以确保其行为符合预期。
jamesc

9

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

然后使用 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)

1
为什么使用assertTrue()代替assertEqual()?至少使用assertEqual(),模块将同时打印结果和期望值。
DenilsonSáMaia'3

没错,assertEqual()更好。我找不到链接,但是我很确定已经读过某个地方使用assertTrue而不是assertEqual。显然,我错了:)我将修复上面的示例。
Vincent Audebert 2014年

12
请注意,如果您在任何字典中都拥有多个键,这将是不可靠的,因为会dumps()使用任意顺序,并且我们不知道中的键顺序result。使用会更好self.assertEqual(json.loads(result), expected_dict)
安德烈·卡伦

6

如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']

-2

我发现自己在一个类似的问题,我使用的属性rendered_content,所以我写了

assertTrue('string' in response.rendered_content) 同样

assertFalse('string' in response.rendered_content) 如果我想测试未呈现字符串

但这也适用于早期建议的方法,

AssertContains(response, 'html string as rendered')

所以我想说第一个比较简单。希望对您有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.