Hello, my name is Federico Capoano,
I enjoy developing cutting-edge websites
and working with creative people.
Over time I realized that waiting more than 15 minutes for my entire test suite to complete was very, very wrong. I've neglected spending time on fine tuning end eningeering tests and now each time I had to run some tests I found myself annoyed, bored, distracted. Quite a productivity killer.
Here's how I achieved a drastic speed up of an entire test suite (roughly 300 tests) of an open source django project designed for crowdsourcing geographic data called nodeshot, which has many database tables running on PostgreSQL (9.1) and Postgis 2.
Hopefully you'll be able to replicate this setup and enjoy the same benefits I'm enjoying now!
First of all I measured my tests by importing this module from the main manage.py, which adds two flags to the test command: "--time" and "--detailed", which output the execution time of each test class and each single test function.
I noticed that there were tests which were taking many seconds to complete, but most tests were not very slow. So I understood that I needed to act on both fronts: in general, by speeding up the database creation procedure and in detail by working on specifc slow test functions.
I tried out quite a few settings, I tried UNLOGGED tables, I even tried to run the database in memory only, but i'll save you time and get straight to the point, the three settings that really made a difference for me were the following ones:
# /etc/postgresql/9.1/main/postgresql.conf fsync = off synchronous_commit = off full_page_writes = off
With these settings alone the total time taken to execute the tests was less than half.
Keep in mind these settings are for development only, I'm assuming you won't care if you lose data in your development environment.
Find out up-to-date information about PostgreSQL non durable options.
Django 1.8 has a new built in feature in the django-admin command:
This flag will avoid destroying the database at the end of each run, which will drastically speed up test execution time. Another good consequence of using this flag is that tests will start really quickly, so running specific test classes for specific modules will take only seconds, which is obviously a great news if you're doing TDD or refactoring your code often.
Find out more about keepdb flag in django 1.8
I fine tuned the default django settings for tests to keep only a few essential middlewares, use the md5 password hasher, and set the celery broker to "memory".
This is more a micro optimization compared to the previous boosts.
I had a few test classes extending LiveServerTestCase in order to perform http requests to the development server, these test classes took a much longer time to complete than the others.
Now the entire test suite takes about 50 seconds to complete, while specific tests for specific modules take seconds, the result is obvious: enhanced productivity, faster refactoring.
I hope I saved some of your time, I hope as well that you'll do better than me and share your results with the open source community.
“ Great news Aymará! Very happy to know this post has inspired you to experiment :-) ”
By Federico Capoano in First DjangoGirls Rome wrap-up & afterthoughts
“ Hi!! I'm a Django Girls coach too. Here, in Argentina, made just what you suggested, splited the workshop in two days. The experiment went just great! Most of the girls achieved to publish the blog from ground 0. It feels great to be helpfull ... ”
By Aymará in First DjangoGirls Rome wrap-up & afterthoughts
“ Send any question to the interop-dev mailing list or open an issue on github. ”
By Federico in Network Topology Visualizer: django-netjsongraph
“ I have a question about Network Topology Collector, can you brief me pls? ”
By Nasrin Akter in Network Topology Visualizer: django-netjsongraph
“ Thanks ! ”
By Alois in How to speed up tests with Django and PostgreSQL