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

时间:2018-01-19 02:10:16

标签: python django unit-testing

我正在一个名为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!\n\nTest Test (family 12) wants to schedule a Birth Preparation and Preferences session within the next day or two.\n\nTest 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,\n\nWe 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.\n\nIf you have any questions, simply reply to this email and someone from our team will get back to you ASAP!\n\nBest,\nLUCY team"
        self.assertEqual(mail.outbox[1].body, expected_body)

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

可能是这种情况吗?我是否可能必须在之前的测试用例中编写一些tearDown方法?或者Django是否在新数据库上运行每个测试,所以这不是必需的?

1 个答案:

答案 0 :(得分:2)

创建id的代码似乎是指expected_body = "Hi!\n\nTest Test (family %s) wants to schedule a Birth Preparation and Preferences session within the next day or two.\n\nTest requested this session on 01/01/12 at 09:00 AM." % family.id 或其他类似字段。如果运行完整的测试套件,它将在创建测试时继续使用下一个唯一编号(在完整套件中它将是第12次创建)。

当自己运行测试时,它是第一次创建。

创建字符串时应该引用id,例如:

{{1}}