Django 测试仅在其模块单独运行时失败



我正在一个名为lucy-web的Django项目中运行测试。如果我运行一个简单的python manage.py test,所有测试都通过:

(venv) Kurts-MacBook-Pro:lucy-web kurtpeek$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
........................
----------------------------------------------------------------------
Ran 24 tests in 22.097s
OK
Destroying test database for alias 'default'...

但是,如果我尝试运行 lucy_web/tests/test_schedule_request.py 中定义的特定测试,它将失败:

(venv) Kurts-MacBook-Pro:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_schedule_request
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.F
======================================================================
FAIL: test_send_schedule_request (lucy_web.tests.test_schedule_request.ScheduleRequestTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/freezegun/api.py", line 495, in wrapper
    result = func(*args, **kwargs)
  File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/lucy_web/tests/test_schedule_request.py", line 44, in test_send_schedule_request
    self.assertEqual(mail.outbox[0].body, expected_body)
AssertionError: 'Hi![17 chars]ily 1) wants to schedule a Birth Preparation a[102 chars] AM.' != 'Hi![17 chars]ily 12) wants to schedule a Birth Preparation [103 chars] AM.'
  Hi!
- Test Test (family 1) wants to schedule a Birth Preparation and Preferences session within the next day or two.
+ Test Test (family 12) wants to schedule a Birth Preparation and Preferences session within the next day or two.
?                    +
  Test requested this session on 01/01/12 at 09:00 AM.
----------------------------------------------------------------------
Ran 2 tests in 2.365s
FAILED (failures=1)
Destroying test database for alias 'default'...

以下是test_schedule_request.py中定义的违规测试:

import json
from django.conf import settings
from django.contrib.auth.models import User
from django.core import mail
from django.test import Client, TestCase
from freezegun import freeze_time
from ..models import Company, Family, Package, SessionType, Session, SessionCategory
class ScheduleRequestTest(TestCase):
    def setUp(self):
        self.client = Client()
        self.url = '/api/v1.0/sessions/send_schedule_request/'
    @freeze_time("2012-01-01 17:00:00")
    def test_send_schedule_request(self):
        user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
        user.first_name = "Test"
        user.last_name = "Test"
        user.save()
        company = Company.objects.create(name='test company')
        package = Package.objects.create(name='test package', company=company)
        family = Family.objects.create(employee_user=user, employee_first_name='Test', employee_last_name='test', employee_email='test@test.net', package=package, point_of_contact='Employee')
        category = SessionCategory.objects.create(name="Birth Prep")
        session_type = SessionType.objects.create(category=category, title='Birth Preparation and Preferences', recommended_timing='32-36 weeks', min_duration=60, max_duration=90, allow_virtual=True, allow_in_person=True, description='some stuff', what_to_expect='other stuff')
        session = Session.objects.create(session_number=1, family=family, session_type=session_type, location=Session.OTHER, other_location='spa', feedback_expert='YES', feedback_session='YES')
        self.client.login(username='john', password='johnpassword')
        response = self.client.post(self.url, json.dumps({'session_id': session.id, 'timeframe': 'within the next day or two'}), content_type="application/json")
        self.assertEqual(response.status_code, 200)
        # Check that session status has been updated
        self.assertEqual(Session.objects.filter(id=session.id)[0].status, 'Times Requested')
        # Check that two emails have been sent.
        self.assertEqual(len(mail.outbox), 2)
        # Verify that the contents of the emails are correct
        self.assertEqual(mail.outbox[0].subject, 'LUCY: Request to Schedule Session')
        self.assertEqual(mail.outbox[0].from_email, settings.DEFAULT_FROM_EMAIL)
        self.assertEqual(mail.outbox[0].to, [settings.CUSTOMER_SERVICE_EMAIL])
        self.assertEqual(mail.outbox[0].reply_to, [user.email])
        expected_body = "Hi!nnTest Test (family 12) wants to schedule a Birth Preparation and Preferences session within the next day or two.nnTest requested this session on 01/01/12 at 09:00 AM."
        self.assertEqual(mail.outbox[0].body, expected_body)
        self.assertEqual(mail.outbox[1].subject, 'LUCY: Request to Schedule Session')
        self.assertEqual(mail.outbox[1].from_email, settings.DEFAULT_FROM_EMAIL)
        self.assertEqual(mail.outbox[1].to, [user.email])
        self.assertEqual(mail.outbox[1].reply_to, [settings.CUSTOMER_SERVICE_EMAIL])
        expected_body = "Hi Test,nnWe received your request for Birth Preparation and Preferences and our team is currently working on scheduling it for you. We will confirm the expert, date & time within 48 hours (or sooner if your request was urgent) via this email address.nnIf you have any questions, simply reply to this email and someone from our team will get back to you ASAP!nnBest,nLUCY team"
        self.assertEqual(mail.outbox[1].body, expected_body)

我已经使用 --verbosity 选项检查了在运行所有测试时此测试是否成功运行。我能想到的唯一解释是,测试在某种程度上不是相互隔离的,一个的成功取决于另一个的setUp

是这样吗?我是否必须在以前的测试用例中编写一些tearDown方法?还是 Django 在新数据库上运行每个测试,所以这应该是不必要的?

创建expected_body的代码似乎引用了 id 或其他类似字段。如果运行完整的测试套件,它将在创建测试时继续使用下一个唯一编号(在完整套件中,它将是第 12 个创建(。

因此,当单独运行测试时,它是第一个创建。

创建字符串时应参考 id,例如:

expected_body = "Hi!nnTest Test (family %s) wants to schedule a Birth Preparation and Preferences session within the next day or two.nnTest requested this session on 01/01/12 at 09:00 AM." % family.id

相关内容

最新更新