Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid warnings on 404 during django test runs?

Just upgraded to Django 1.3. My test suite is now showing a bunch of useless warnings like this every time I check that a given URL is 404. It didn't do that under Django 1.2.

For example, let's say we have views and URLs wired up such that this test passes:

def test_foo(self):
    response = self.client.get('/foo/bar/')
    self.assertEqual(response.status_code, 200)
    response = self.client.get('/foo/bar2/')
    self.assertEqual(response.status_code, 404)

Although the test passes, the 404 (which we expect) triggers a warning to the console:

.WARNING Not Found: /foo/bar2/

This is just useless noise; I have about 30 of them in one of my current test suites.

Is there a way to silence those just during tests? I'd like to leave them on during normal operation. And I don't think I want to filter out all warnings from the 'django.request' logger.

like image 544
slinkp Avatar asked Jun 16 '11 19:06

slinkp


People also ask

How do I skip a Django test?

Just trick it to always skip with the argument True : @skipIf(True, "I don't want to run this test yet") def test_something(): ... If you are looking to simply not run certain test files, the best way is probably to use fab or other tool and run particular tests.

How do I run test coverage in Django?

With Django's Test Runner. If you're using manage.py test , you need to change the way you run it. You need to wrap it with three coverage commands like so: $ coverage erase # Remove any coverage data from previous runs $ coverage run manage.py test # Run the full test suite Creating test database for alias 'default'.. ...

Does Django use Pytest or Unittest?

Django's unit tests use a Python standard library module: unittest . This module defines tests using a class-based approach.

What is client in Django test?

The test client. The test client is a Python class that acts as a dummy web browser, allowing you to test your views and interact with your Django-powered application programmatically.


2 Answers

The warning is coming from here: http://code.djangoproject.com/svn/django/trunk/django/core/handlers/base.py

What you want to do is set the logging threshold of the 'django.request' module to something above WARNING (e.g. ERROR) at the beginning of the test, and then set it back afterward.

Try something like this:

import logging

#before tests
logger = logging.getLogger('django.request')
previous_level = logger.getEffectiveLevel()
logger.setLevel(logging.ERROR)

#after tests
logger.setLevel(previous_level)
like image 152
jterrace Avatar answered Sep 16 '22 15:09

jterrace


I know some years passed by but for others looking for this question the following might be helpful.

Based on @jterrace solution you could easily implement a decorator function like this:

import logging

def prevent_request_warnings(original_function):
    """
    If we need to test for 404s or 405s this decorator can prevent the
    request class from throwing warnings.
    """
    def new_function(*args, **kwargs):
        # raise logging level to ERROR
        logger = logging.getLogger('django.request')
        previous_logging_level = logger.getEffectiveLevel()
        logger.setLevel(logging.ERROR)

        # trigger original function that would throw warning
        original_function(*args, **kwargs)

        # lower logging level back to previous
        logger.setLevel(previous_logging_level)

    return new_function

Using this you could write your code like this:

@prevent_request_warnings
def test_foo(self):
    response = self.client.get('/foo/bar/')
    self.assertEqual(response.status_code, 200)
    response = self.client.get('/foo/bar2/')
    self.assertEqual(response.status_code, 404)
like image 44
Nico Knoll Avatar answered Sep 18 '22 15:09

Nico Knoll