Django 测试中禁用了 Airbrake 通知?
Airbrake notifications disabled in Django tests?
我配置了一个名为 lucy_web
的 Django 应用,使用 pybrake
将错误记录到 Airbrake。在 lucy_web
层次结构 lucy_web.lib.session_recommendations
的模块中,我定义了一个测试函数:
import logging
logger = logging.getLogger(__name__)
def log_something():
logger.error("Logging something...")
如果我从 Django shell 调用这个函数,就像这样:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from lucy_web.lib.session_recommendation import *
In [2]: log_something()
我看到一封错误邮件:
但是,如果我定义了一个测试,并尝试从那里调用它,我没有看到任何新的错误实例出现:
from django.test import TestCase
from django.core import mail
class SessionRecommendationTestCase(TestCase):
def test_airbrake_notification_if_session_type_does_not_exist(self):
from lucy_web.lib.session_recommendation import log_something
log_something()
import ipdb; ipdb.set_trace()
运行 这并没有导致任何新的错误实例出现在 Airbrake 仪表板中。此外,mail.outbox
为空:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_session_recommendation.SessionRecommendationTestCase.test_airbrake_notification_if_session_type_does_not_exist
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
--Return--
None
> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/lucy_web/tests/test_session_recommendation.py(377)test_airbrake_notification_if_session_type_does_not_exist()
375 from lucy_web.lib.session_recommendation import log_something
376 log_something()
--> 377 import ipdb; ipdb.set_trace()
ipdb> mail.outbox
[]
据我所知 https://docs.djangoproject.com/en/2.0/topics/testing/tools/#email-services,在一次测试中,Django 将 Django 发送的所有电子邮件重定向到虚拟发件箱 mail.outbox
。不过,我不希望 Airbrake 出现这种情况,因为电子邮件可能是由他们的后端发送的——如果是这样的话,我不希望 mail.outbox
为空。
为什么我没有收到任何 Airbrake 测试通知?它是否更通用,比如在测试期间所有日志记录都是 disabled/captured?
我通过在 pybrake.Notifier
的 send_notice
方法中设置跟踪来验证它不会在单元测试中被调用,而当我调用函数 'manually' 来自 Django shell.
为了仍然获得测试覆盖率,我解决了这个问题,只是断言 logger.error
被调用:
from django.test import TestCase
from unittest.mock import patch
class SessionRecommendationTestCase(TestCase):
@patch('lucy_web.lib.session_recommendation.logger.error')
def test_create_session_from_non_existent_session_type_title_triggers_error_logging(self, mock_error):
title = "Being Awesome" # Title of a non-existent session type
_create_sessions([title])
mock_error.assert_called_with(
f"Tried to create a session of type '{title}', but no such session type was found in the database.")
这是我要测试的实际功能:
def _create_sessions(title_list, starting_number=1, **kwargs):
'''Auxiliary function to create sessions from a list of SessionType titles'''
session_number = starting_number
for title in title_list:
session_type = SessionType.objects.filter(title=title).first()
if session_type:
Session.objects.create(
session_type=session_type,
session_number=session_number,
**kwargs)
session_number += 1
else:
logger.error(
f"Tried to create a session of type "
f"'{title}', but no such session type was found in the database.")
此测试通过:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_session_recommendation.SessionRecommendationTestCase.test_create_session_from_non_existent_session_type_title_triggers_error_logging
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
Destroying test database for alias 'default'...
我配置了一个名为 lucy_web
的 Django 应用,使用 pybrake
将错误记录到 Airbrake。在 lucy_web
层次结构 lucy_web.lib.session_recommendations
的模块中,我定义了一个测试函数:
import logging
logger = logging.getLogger(__name__)
def log_something():
logger.error("Logging something...")
如果我从 Django shell 调用这个函数,就像这样:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from lucy_web.lib.session_recommendation import *
In [2]: log_something()
我看到一封错误邮件:
但是,如果我定义了一个测试,并尝试从那里调用它,我没有看到任何新的错误实例出现:
from django.test import TestCase
from django.core import mail
class SessionRecommendationTestCase(TestCase):
def test_airbrake_notification_if_session_type_does_not_exist(self):
from lucy_web.lib.session_recommendation import log_something
log_something()
import ipdb; ipdb.set_trace()
运行 这并没有导致任何新的错误实例出现在 Airbrake 仪表板中。此外,mail.outbox
为空:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_session_recommendation.SessionRecommendationTestCase.test_airbrake_notification_if_session_type_does_not_exist
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
--Return--
None
> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/lucy_web/tests/test_session_recommendation.py(377)test_airbrake_notification_if_session_type_does_not_exist()
375 from lucy_web.lib.session_recommendation import log_something
376 log_something()
--> 377 import ipdb; ipdb.set_trace()
ipdb> mail.outbox
[]
据我所知 https://docs.djangoproject.com/en/2.0/topics/testing/tools/#email-services,在一次测试中,Django 将 Django 发送的所有电子邮件重定向到虚拟发件箱 mail.outbox
。不过,我不希望 Airbrake 出现这种情况,因为电子邮件可能是由他们的后端发送的——如果是这样的话,我不希望 mail.outbox
为空。
为什么我没有收到任何 Airbrake 测试通知?它是否更通用,比如在测试期间所有日志记录都是 disabled/captured?
我通过在 pybrake.Notifier
的 send_notice
方法中设置跟踪来验证它不会在单元测试中被调用,而当我调用函数 'manually' 来自 Django shell.
为了仍然获得测试覆盖率,我解决了这个问题,只是断言 logger.error
被调用:
from django.test import TestCase
from unittest.mock import patch
class SessionRecommendationTestCase(TestCase):
@patch('lucy_web.lib.session_recommendation.logger.error')
def test_create_session_from_non_existent_session_type_title_triggers_error_logging(self, mock_error):
title = "Being Awesome" # Title of a non-existent session type
_create_sessions([title])
mock_error.assert_called_with(
f"Tried to create a session of type '{title}', but no such session type was found in the database.")
这是我要测试的实际功能:
def _create_sessions(title_list, starting_number=1, **kwargs):
'''Auxiliary function to create sessions from a list of SessionType titles'''
session_number = starting_number
for title in title_list:
session_type = SessionType.objects.filter(title=title).first()
if session_type:
Session.objects.create(
session_type=session_type,
session_number=session_number,
**kwargs)
session_number += 1
else:
logger.error(
f"Tried to create a session of type "
f"'{title}', but no such session type was found in the database.")
此测试通过:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py test lucy_web.tests.test_session_recommendation.SessionRecommendationTestCase.test_create_session_from_non_existent_session_type_title_triggers_error_logging
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
Destroying test database for alias 'default'...