python - 尽管两个查询集在 shell 中打印出相同的内容,但 Django 的 assertQuerysetEqual() 方法还是失败了?

标签 python django django-testing

我有一个 Family 和一个具有一对多关系的 Session,这样一个实例 family 就有一个 session 集。此外,Session 有一个session_number 字段,它是一个整数。

我有两个 Family 实例,family1family2,如果我打印出它们的 session_set.order_by(' session_number')ipdb 调试器中,我发现它们看起来完全一样:

ipdb> family1.session_set.order_by('session_number')
<QuerySet [<Session: Welcome>, <Session: First-Time Parents: The Basics of Birth>, <Session: Initial Postpartum Lactation>, <Session: Sleep Techniques for New Babies>, <Session: Breastfeeding Preparation>, <Session: Newborn Care Basics>, <Session: Easing the Transition Back to Work>, <Session: Preparing for Parenting>, <Session: Decoding Baby Cues>, <Session: Postpartum Doula Support>, <Session: First-Time Parents: Birth Prep Q&A>, <Session: Postpartum Lactation Follow-Up>, <Session: Sleep Training for 4 Months & Beyond>, <Session: Mental Wellness in Pregnancy>, <Session: Infant CPR>, <Session: Prenatal Pelvic Physical Therapy>, <Session: Prenatal Massage>]>
ipdb> family2.session_set.order_by('session_number')
<QuerySet [<Session: Welcome>, <Session: First-Time Parents: The Basics of Birth>, <Session: Initial Postpartum Lactation>, <Session: Sleep Techniques for New Babies>, <Session: Breastfeeding Preparation>, <Session: Newborn Care Basics>, <Session: Easing the Transition Back to Work>, <Session: Preparing for Parenting>, <Session: Decoding Baby Cues>, <Session: Postpartum Doula Support>, <Session: First-Time Parents: Birth Prep Q&A>, <Session: Postpartum Lactation Follow-Up>, <Session: Sleep Training for 4 Months & Beyond>, <Session: Mental Wellness in Pregnancy>, <Session: Infant CPR>, <Session: Prenatal Pelvic Physical Therapy>, <Session: Prenatal Massage>]>

但是,如果我将这些查询集输入 assertQuerysetEqual ,我得到一个测试失败:

ipdb> self.assertQuerysetEqual(family1.session_set.order_by('session_number'), family2.session_set.order_by('session_number'))
*** AssertionError: Lists differ: ['<Session: Welcome>', '<Session: First-Ti[642 chars]ge>'] != [<Session: Welcome>, <Session: First-Time [608 chars]age>]

First differing element 0:
'<Session: Welcome>'
<Session: Welcome>

Diff is 2186 characters long. Set self.maxDiff to None to see it.

下面是将 maxDiff 设置为 None 的更详细比较:

ipdb> self.maxDiff = None
ipdb> self.assertQuerysetEqual(family1.session_set.order_by('session_number'), family2.session_set.order_by('session_number'))
*** AssertionError: Lists differ: ['<Session: Welcome>', '<Session: First-Ti[642 chars]ge>'] != [<Session: Welcome>, <Session: First-Time [608 chars]age>]

First differing element 0:
'<Session: Welcome>'
<Session: Welcome>

- ['<Session: Welcome>',
?  -                  -

+ [<Session: Welcome>,
-  '<Session: First-Time Parents: The Basics of Birth>',
?  -                                                  -

+  <Session: First-Time Parents: The Basics of Birth>,
-  '<Session: Initial Postpartum Lactation>',
?  -                                       -

+  <Session: Initial Postpartum Lactation>,
-  '<Session: Sleep Techniques for New Babies>',
?  -                                          -

+  <Session: Sleep Techniques for New Babies>,
-  '<Session: Breastfeeding Preparation>',
?  -                                    -

+  <Session: Breastfeeding Preparation>,
-  '<Session: Newborn Care Basics>',
?  -                              -

+  <Session: Newborn Care Basics>,
-  '<Session: Easing the Transition Back to Work>',
?  -                                             -

+  <Session: Easing the Transition Back to Work>,
-  '<Session: Preparing for Parenting>',
?  -                                  -

+  <Session: Preparing for Parenting>,
-  '<Session: Decoding Baby Cues>',
?  -                             -

+  <Session: Decoding Baby Cues>,
-  '<Session: Postpartum Doula Support>',
?  -                                   -

+  <Session: Postpartum Doula Support>,
-  '<Session: First-Time Parents: Birth Prep Q&A>',
?  -                                             -

+  <Session: First-Time Parents: Birth Prep Q&A>,
-  '<Session: Postpartum Lactation Follow-Up>',
?  -                                         -

+  <Session: Postpartum Lactation Follow-Up>,
-  '<Session: Sleep Training for 4 Months & Beyond>',
?  -                                               -

+  <Session: Sleep Training for 4 Months & Beyond>,
-  '<Session: Mental Wellness in Pregnancy>',
?  -                                       -

+  <Session: Mental Wellness in Pregnancy>,
-  '<Session: Infant CPR>',
?  -                     -

+  <Session: Infant CPR>,
-  '<Session: Prenatal Pelvic Physical Therapy>',
?  -                                           -

+  <Session: Prenatal Pelvic Physical Therapy>,
-  '<Session: Prenatal Massage>']
?  -                           -

+  <Session: Prenatal Massage>]

比较似乎“不同步”。但是,session_number 也是一样的:

ipdb> [(session.session_number, str(session.session_type)) for session in family1.session_set.order_by('session_number')]
[(0, 'Welcome'), (1, 'First-Time Parents: The Basics of Birth'), (2, 'Initial Postpartum Lactation'), (3, 'Sleep Techniques for New Babies'), (4, 'Breastfeeding Preparation'), (5, 'Newborn Care Basics'), (6, 'Easing the Transition Back to Work'), (7, 'Preparing for Parenting'), (8, 'Decoding Baby Cues'), (9, 'Postpartum Doula Support'), (10, 'First-Time Parents: Birth Prep Q&A'), (11, 'Postpartum Lactation Follow-Up'), (12, 'Sleep Training for 4 Months & Beyond'), (13, 'Mental Wellness in Pregnancy'), (14, 'Infant CPR'), (15, 'Prenatal Pelvic Physical Therapy'), (16, 'Prenatal Massage')]
ipdb> [(session.session_number, str(session.session_type)) for session in family2.session_set.order_by('session_number')]
[(0, 'Welcome'), (1, 'First-Time Parents: The Basics of Birth'), (2, 'Initial Postpartum Lactation'), (3, 'Sleep Techniques for New Babies'), (4, 'Breastfeeding Preparation'), (5, 'Newborn Care Basics'), (6, 'Easing the Transition Back to Work'), (7, 'Preparing for Parenting'), (8, 'Decoding Baby Cues'), (9, 'Postpartum Doula Support'), (10, 'First-Time Parents: Birth Prep Q&A'), (11, 'Postpartum Lactation Follow-Up'), (12, 'Sleep Training for 4 Months & Beyond'), (13, 'Mental Wellness in Pregnancy'), (14, 'Infant CPR'), (15, 'Prenatal Pelvic Physical Therapy'), (16, 'Prenatal Massage')]

为什么 assertQuerysetEqual 在这里没有按预期工作?

最佳答案

这是因为 assertQuerysetEqual 不会将查询集与另一个查询集进行比较,而是将查询集与值列表进行比较。

来自 assertQuerysetEqual's documentation :

TransactionTestCase.assertQuerysetEqual(qs, values, transform=repr, ordered=True, msg=None)

Asserts that a queryset qs returns a particular list of values values.

The comparison of the contents of qs and values is performed using the function transform; by default, this means that the repr() of each value is compared.

因此您应该将第二个参数转换为列表:

self.assertQuerysetEqual(family1.session_set.order_by('session_number'), list(family2.session_set.order_by('session_number')))

关于python - 尽管两个查询集在 shell 中打印出相同的内容,但 Django 的 assertQuerysetEqual() 方法还是失败了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51255851/

相关文章:

python - 通过socket/ftp python从服务器发送文件到客户端

python - 在 Flask Debug模式下禁用默认/控制台路由的最佳方法是什么?

python - 为循环优化 Django Queryset

python - Django LiveServer测试用例 : User created in in setUpClass method not available in test_method?

python - 使用 pandas 和 numpy 参数化堆栈溢出的用户数和声誉

python - 如何编辑 Django 表单错误消息的 CSS?

python - 使用布局对象 AppendText 更改 django-crispy-forms 中仅一个字段的小部件

python - VSCode 调试,将文件作为 Python 模块传递

django - TemplateView的get方法: object has no attribute 'request'

python - 从python中的矩阵中提取子元素