Make tests a little less noisy

This commit is contained in:
Seamus Johnston 2022-11-17 07:43:53 -06:00
parent f5c117df9f
commit 523c699865
No known key found for this signature in database
GPG key ID: 2F21225985069105
3 changed files with 106 additions and 2 deletions

49
src/api/tests/common.py Normal file
View file

@ -0,0 +1,49 @@
import os
import logging
from contextlib import contextmanager
def get_handlers():
"""Obtain pointers to all StreamHandlers."""
handlers = {}
rootlogger = logging.getLogger()
for h in rootlogger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
for logger in logging.Logger.manager.loggerDict.values():
if not isinstance(logger, logging.PlaceHolder):
for h in logger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
return handlers
@contextmanager
def less_console_noise():
"""
Context manager to use in tests to silence console logging.
This is helpful on tests which trigger console messages
(such as errors) which are normal and expected.
It can easily be removed to debug a failing test.
"""
restore = {}
handlers = get_handlers()
devnull = open(os.devnull, "w")
# redirect all the streams
for handler in handlers.values():
prior = handler.setStream(devnull)
restore[handler.name] = prior
try:
# run the test
yield
finally:
# restore the streams
for handler in handlers.values():
handler.setStream(restore[handler.name])

View file

@ -7,6 +7,7 @@ from django.contrib.auth import get_user_model
from django.test import TestCase, RequestFactory from django.test import TestCase, RequestFactory
from ..views import available, _domains, in_domains from ..views import available, _domains, in_domains
from .common import less_console_noise
API_BASE_PATH = "/api/v1/available/" API_BASE_PATH = "/api/v1/available/"
@ -104,10 +105,12 @@ class AvailableAPITest(TestCase):
def test_available_post(self): def test_available_post(self):
"""Cannot post to the /available/ API endpoint.""" """Cannot post to the /available/ API endpoint."""
with less_console_noise():
response = self.client.post(API_BASE_PATH + "nonsense") response = self.client.post(API_BASE_PATH + "nonsense")
self.assertEqual(response.status_code, 405) self.assertEqual(response.status_code, 405)
def test_available_bad_input(self): def test_available_bad_input(self):
self.client.force_login(self.user) self.client.force_login(self.user)
with less_console_noise():
response = self.client.get(API_BASE_PATH + "blah!;") response = self.client.get(API_BASE_PATH + "blah!;")
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)

View file

@ -1,7 +1,57 @@
import os
import logging
from contextlib import contextmanager
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model, login from django.contrib.auth import get_user_model, login
def get_handlers():
"""Obtain pointers to all StreamHandlers."""
handlers = {}
rootlogger = logging.getLogger()
for h in rootlogger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
for logger in logging.Logger.manager.loggerDict.values():
if not isinstance(logger, logging.PlaceHolder):
for h in logger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
return handlers
@contextmanager
def less_console_noise():
"""
Context manager to use in tests to silence console logging.
This is helpful on tests which trigger console messages
(such as errors) which are normal and expected.
It can easily be removed to debug a failing test.
"""
restore = {}
handlers = get_handlers()
devnull = open(os.devnull, "w")
# redirect all the streams
for handler in handlers.values():
prior = handler.setStream(devnull)
restore[handler.name] = prior
try:
# run the test
yield
finally:
# restore the streams
for handler in handlers.values():
handler.setStream(restore[handler.name])
class MockUserLogin: class MockUserLogin:
def __init__(self, get_response): def __init__(self, get_response):
self.get_response = get_response self.get_response = get_response
@ -23,3 +73,5 @@ class MockUserLogin:
response = self.get_response(request) response = self.get_response(request)
return response return response