Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing with django-pipeline

I have problems unit testing views of an application that uses django-pipeline? Whenever I perform a client.get() on any URL, it produces the following exception:

ValueError: The file 'css/bootstrap.css' could not be found with <pipeline.storage.PipelineCachedStorage object at 0x10d544950>.

The fact that it is bootstrap.css is of course not important, but that I'm unable to execute view rendering due to this exception.

Any guide / tips are welcome!

like image 817
Manne Avatar asked Oct 10 '12 10:10

Manne


1 Answers

I ran into a similar problem. However, setting

STATICFILES_STORAGE='pipeline.storage.NonPackagingPipelineStorage'

when running the tests only partly solved my issue. I also had to disable the pipeline completely if you want to run LiverServerTestCase tests without having to calling 'collecstatic' before running the tests:

PIPELINE_ENABLED=False

Since django 1.4 it's fairly easy to modify settings for tests - there is a handy decorator that works for methods or TestCase classes:

https://docs.djangoproject.com/en/1.6/topics/testing/tools/#overriding-settings

e.g.

from django.test.utils import override_settings

@override_settings(STATICFILES_STORAGE='pipeline.storage.NonPackagingPipelineStorage', PIPELINE_ENABLED=False)
class BaseTestCase(LiveServerTestCase):
    """
    A base test case for Selenium
    """

    def setUp(self):
        ...

However this produced inconsistent results as @jrothenbuhler describes in his answer. Regardless, this is less than ideal if you are running integration tests - you should mimic production as much as possible to catch any potential issues. It appears django 1.7 has a solution for this in the form of a new test case "StaticLiveServerTestCase". From the docs: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#django.contrib.staticfiles.testing.StaticLiveServerCase

This unittest TestCase subclass extends django.test.LiveServerTestCase.

Just like its parent, you can use it to write tests that involve running the code under test and consuming it with testing tools through HTTP (e.g. Selenium, PhantomJS, etc.), because of which it’s needed that the static assets are also published.

I haven't tested this, but sounds promising. For now I'm doing what @jrothenbuhler in his solution using a custom test runner, which doesn't require you to run collectstatic. If you really, really wanted it to run collectstatic you could do something like this:

from django.conf import settings
from django.test.simple import DjangoTestSuiteRunner
from django.core.management import call_command

class CustomTestRunner(DjangoTestSuiteRunner):
    """
    Custom test runner to get around pipeline and static file issues
    """

    def setup_test_environment(self):
        super(CustomTestRunner, self).setup_test_environment()
        settings.STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'
        call_command('collectstatic', interactive=False)

In settings.py

TEST_RUNNER = 'path.to.CustomTestRunner'
like image 148
mynameistechno Avatar answered Sep 18 '22 15:09

mynameistechno