Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functional tests in Django reusable apps

I'm writing a Django reusable app. It's not a usual app which can be used on its own. It requires other apps to be usable just like django.contrib.admin or django-dajaxice do.

My current project tree looks like this:

django-myapp/
    docs/
        some.rst
        docs.rst
        ...
    myapp/
        static/
            myapp/
                some_js_stuff.js
        templatetags/
            some_file.py
        __init__.py
        base.py
        manager.py
        ...
    unit_tests/
        __init__.py
        test_base.py
        test_manager.py
    functional_tests/
        __init__.py
        functional_tests.py
        urls.py
    README.rst
    LICENSE
    requirements.txt
    requirements-test.txt
    setup.py
    ...

Unit tests are easy - I'm just testing my code so I don't need complete Django environment to run them. Simple ./setup.py test works perfectly.

Functional testing is the tricky part. I would like to use selenium so I need running dev server and this requires whole Django environment. I'm trying to use django.test.LiveServerTestCase but with no success (It looks like there were no urls defined, setting ROOT_URLCONF in settings and urls attribute in class didn't help).

Every piece of documentation I've found, every question on stackoverflow tells about testing Django apps inside Django project. And here is my question: what is the best (and working) way to run functional/integration tests of reusable app without setting up complete Django project?

like image 447
Patryk Ściborek Avatar asked Oct 20 '22 13:10

Patryk Ściborek


1 Answers

As Nathan says its hard to test a unit in a whole stack, without the stack. So you have to have a settings file. Have a look at how the excellent django-debug-toolbar app does it:

It has a Makefile with a test_selenium rule:

test_selenium:
    DJANGO_SELENIUM_TESTS=true DJANGO_SETTINGS_MODULE=tests.settings \
        django-admin.py test tests

And in its tests module it has a bare bones settings.py with the bare necessities:

  • INSTALLED_APPS with the app under test
  • ROOT_URLCONF wich points to the urls.py
  • stuff like MIDDLEWARE_CLASSES that you may skip because you have none.

and a test_integration.py

@skipUnless('DJANGO_SELENIUM_TESTS' in os.environ, "selenium tests not requested")
class DebugToolbarLiveTestCase(LiveServerTestCase):
    ...

Study their setup. Start at the Makefile and dig down making sure you understand why everything is there.

I like that setup because integration/functional tests tend to be dogslow. Understandably, they test the whole stack with all its moving parts. Their Makefile gives an easy way to skip them. If I were to have a reusable app that uses Javascript, I'd have a look at jasmine too. Or some other tool to unittest the javascript. Because running the slow integrationtests just to see if the js units work is a pain.

like image 126
Chris Wesseling Avatar answered Oct 27 '22 10:10

Chris Wesseling