Rails and Django - Development Cycle (part 14/15)
Debugging
While most of the discussion here so far has been about architecture design and API's for writing code, the bulk of a mortal programmers' time is spent troubleshooting and debugging. To the extent that a framework can help prevent bugs before they happen, all the better. But eventually you need to get down with it.
First, to state the obvious (I hope): To use any tool like a web development framework, you need to learn the programming language! (Seriously, too many people jump in before accepting that). Your debugging environment is primarily a function of the programming language.
Tools in your debugging arsenal include:
- Interactive command line console
- Framework generated error pages
- Dumping values from your program to a page
- Log files
- Breakpoints
Both Ruby and Python are interpretive languages, and their program are often referred to as scripts. Both languages offer an interactive shell-- a command line environment where you can run scripts and execute expressions for testing, debugging, and quick operations. The Ruby console is invoked with “irb”. The Python console is invoked with “python”, or the more powerful “ipython”.
When a web application encounters an error, the framework may present an error page with details of the error condition, what file it occurred in, the values of variables, a stack trace, HTTP header, POST variables, and so on. Debugging should be enabled in your development environment and disabled in your production one (as these error pages could contain sensitive details about your site).
Inside your code and templates you may need to dump the values of variables. Both framework's languages provide methods for converting variables to strings and including them in the HTTP response buffer (that is, your page). Rails has a “debug” helper method.
Log files are another invaluable tool for seeing what's going on (and going wrong) in your application. Both frameworks (optionally) generate log files, and you can add your own messages for tracing through problems.
Finally, you may need insert a “breakpoint” in your program, to stop execution and then examine for example the value of specific objects. Rails provides a built in breakpoint method, for use in a local development environment only. For Django you'd need to go to an IDE (as far as I know).
Some people like to work within an IDE (interactive development environment). The Rails folks say this is completely unnecessary but possible. A couple of popular ones that work with Python and Ruby are Eclipse and Komodo . (The Python plugin for Eclipse is Pydev ).
Conclusion: It appears the debugging tools for both frameworks are mature and comparable, rated 3-3.
Testing
A really great way to preempt bugs is to test. Write code, then write tests that exercise the code, and validate the results. When you change things, you can re-run the tests to make sure things still work. Testing should not be an afterthought. (Taken to the extreme, test-driven development methodology encourages writing the test cases first, and then write the code to be tested.)
Testing also includes performance testing and profiling, for fine tuning your deployed application.
Robust testing tools are available in both the Ruby and Python programming environments.
Rails
Rails make full use of the Ruby language testing tools, and adds a nice testing framework within Rails. Each time you generate a new model and controller, Rails creates stub files in the project's test/ subdirectory, ready and waiting for you to code them up.
Test scripts typically call the model and controller methods, and assert the results. Rails makes a clear distinction between “unit tests” for testing models (e.g. file test/unit/mymodel_test.rb), “functional tests” for testing controllers (e.g. file test/functional/mycontr_controller_test.rb), and “integration tests” for testing the work flow through your application. (Taken further, you can even develop a domain-specific language for high level application testing).
Test fixtures define a separate database specifically for testing. When you run a test, the database is re-created from the fixtures, ensuring that your tests are repeatable and consistent. Rails fixtures are written in YAML (.yml files), a simple language.
Django
With the standard Python doctest module, you run some tests of a method in the interactive console, and then paste the results from the console into the program script as a docstring comment. Then when you run doctest on that file, it re-plays the test and compares the results. Thus, the code, test cases, and expected results are all maintained in the same file.
You can also write separate test scripts, saved in tests.py file. Django's test runner looks for doctest and tests.py in your application directory.
An alternative is the standard Python unittest module, for which you write unit tests for your models.
Python's test client can be used to simulate the request/response interaction of your application with browsers.
Django does not have test fixtures, although they're said to be planned.
Opinion
None of the tools described above are replacements for browser automation testing frameworks, such as Twill and Selenium for testing of your web application independent of your specific application framework and language.
Programmers should write tests to test their own code. Other tests might be written by a separate QA person, to double check the code and perform application integration. In this case, maintaining test scripts in a separate test directory is better.
Much like documenting code with comments, writing tests is a necessary burden that requires professional discipline, because programmers normally just want to write code. The fact that Rails generators create test file stubs is like your father reminding you to do your homework, a not-so-subtle reminder of what you ought to be doing.
With regard to test fixtures, for smaller tests they seem fine. For more extensive testing with larger datasets, it seems it'd be burdensome to create and maintain long scripts and easier to just copy a previously created database to the test one.
Conclusion: While testing tools are largely available in both, Rails has more successfully integrated testing into the development cycle. I rate Rails 4, Django 3 for testing.
Deployment
While really not a function of the web development framework, deployment of your application to a live site is certainly an important part of the development cycle.
I will not go into the issues of setting up and administrating a website for Ruby or Python, nor the decisions related to Apache versus Lighttp web servers, etc. There are always issues and obviously the typical ones have been worked out. Many people will prefer to use a hosting service.
Scalability is also a consideration, to support high traffic volumes. Both Rails and Django are scalable to multiple servers. We rely on outside experts in service-oriented architecture (SOA) to configure a production environment.
Rails
Rails comes setup to easily switch between different configuration environments, namely, development, testing, and production. Each environment may have its own database, and its own configuration parameters (including logging, caching, debugging, and so on). You can even specify the version of Rails to use, so you can roll back to a previous version, for instance, after an upgrade.
Rails includes Capistrano, a Ruby-based utility for setting up a repeatable deployment scheme on remote servers. Capistrano assumes you store your code in a source code repository (such as subversion), and it assumes you are deploying to a Unix based server. Once setup, it's easy to update our live server from your (tested) development repository.
Configuring your web server is relatively tricky. Mongrel is a back-end Ruby web server. A recommended server configuration for Rails uses HTTP proxying to one or more Mongrel servers. Rails has problems with fast_cgi, and is not recommended.
There are hosting services dedicated to hosting Ruby on Rails applications. People have reported problems with some of them, so choose carefully. A recent review can be found at http://nubyonrails.topfunky.com/articles/2007/02/24/the-host-with-the-most
Django
Apache with mod_python currently is the preferred setup for using Django on a production server. (It can also run with fast_cgi). It all seems pretty standard as for any Python app, nothing special.
Opinion
A Django deployment appears easier, especially for smallish sites where HTTP proxying wouldn't be necessary. Otherwise, Django and Rails are comparable.
Rails has thought through the workflow of development-to-deployment more thoroughly and helps make it easier, like the different configuration environments and the Capistrano tool.
Conclusion: Rails gets a 4 for being more helpful, versus 3 for Django, even though Django may be easier for hosting small sites.




Rails and Django - Development Cycle (part 14/15)
Posted by: Brent Larsen on June 25, 2008 01:50 AM#