Category: Windmill

Running Windmill tests from Django

Posted by on November 02, 2008

It’s usually a good idea to document cool features you write and tell people about them. I totally forgot about this one, which I wrote during DjangoCon a few months back.

A few years ago I wrote a patch for live server support in Django. The patch fell out of sync with trunk and was picked up a year or so later and substantially improved. But the patch didn’t end up making it in for 1.0 :( . Luckily the code is simple enough that I was able to use it windmill and add live server support to any Django 1.0 install by dynamically overriding and changing the classes that we need to start and stop a live test server for you django project.

After it’s all said and done this makes it dirt simple to bootstrap windmill tests from your Django unittests, all you need to do is define a single test class along side your other django unittests pointing to the directory of windmill tests you want to run and which browser you want to run them in and windmill’s django support will automatically start a live django server and run your windmill tests against it.

from os import path
from windmill.authoring import djangotest 
 
class WindmillTests(djangotest.WindmillDjangoUnitTest):
    test_dir = path.join(path.dirname(path.abspath(__file__)), 'windmilltests')
    browser = 'firefox'

This is also all written up on a wiki page along with some of the caveats.

Windmill 0.9.1 Released

Posted by on October 13, 2008

I didn’t think we’d be doing any notable windmill releases until 1.0. Boy was I wrong!

Seriously Faster

On Wednesday Adam messaged me and said that the windmill startup time was too slow. He was right, we’ve know about this for a while but hadn’t put a lot of serious thought in to how we could reduce it.
The issue here was was that we have about 50 JavaScript files that need to get loaded for windmill to start.

Enter windmill-compressor, a new url namespace we added that concats all the js windmill needs in to one file and minifies it. We do this dynamically when windmill starts up, because adding a “build” step would just be too….. Java.

That reduced the startup time from 5-10 seconds to around 2 seconds. But that wasn’t good enough. We saw that most of that startup time was blocking waiting for the compressor to finish, so I threaded it when we start the windmill service and it does the compression while we wait for the browser to start up.

In all, windmill startup times are about 10x faster than 0.9!

Adam also decided to make our page load wait code a bit more aggressive which made not only startup times faster but all of our tests!

Native JavaScript Test Framework

We tied up the loose ends on the JavaScript testing framework and it can now shutdown all of windmill in it’s own teardown, hello continuous integration for native JavaScript tests :)

This was the last thing holding us back from promoting this along side the Python test authoring library.

We Love Firebug

In 0.9 we introduced Firebug Lite integration for windmill on all browsers. But when you’re using Firefox you probably still want to use the full Firebug extension, which is easy enough to integrate since we use mozrunner for Firefox launching.

Windmill now has a “firebug” command line argument that installs the full Firebug
extension when launching Firefox.

Firebug Lite in Windmill

Posted by on September 08, 2008

Everyone knows how awesome Firebug is. But for those times you have the unfortunate task of debugging in a browser that isn’t Firefox the Firebug team recently put out a new release of Firebug Lite.

For some time now we’ve always had a shell in Windmill for debugging but it was never as nice as the Firebug shell and maintaining that code was kind of a pain. In the recent 0.8.2 release of Windmill we dropped our old shell code and fully integrated Firebug Lite so that whenever you need to debug a test in any browser you can open Firebug Lite in the target application by clicking a single link in the Windmill IDE.

I can’t even begin to explain how much easier this is going to make writing and debugging tests in Windmill.

DjangoCon 2008

Posted by on September 08, 2008

I had the pleasure of attending the very first DjangoCon this last weekend.

I’ve attended a lot of conferences; big conferences, small conferences, very targetted conferences and very broad conferences. I think DjangoCon may have been the best conference I’ve ever been to.

Over the years what I’ve learned to truly value about a conference is; meeting with people in the community, learning and understanding things I care about that would be harder to learn from reading than listening to a speaker, and just generally having a good time. DjangoCon was fantastic on all fronts. Being so targeted (people who use Django) there weren’t many talks that I didn’t care about and the people speaking were in all cases the best person to be speaking about a particular topic. The Django community is my favorite open source community, beating out the larger Python community by a small margin. Everyone is nice, helpful, and rarely suffer from even a marginal amount of smugness. Add food, decent wifi, and Cal’s talk “Why I hate Django” and you definitely cover the “having a good time” bit.

AppEngine

I messed with AppEngine for a couple weeks when it was first released. There were some serious rough edges that I decided I couldn’t deal with and I really didn’t completely get my head around the datastore.

Guido on AppEngine

Seeing Guido’s talk I noticed that those rough edges have been smoothed out and the development environment seems nicer, not to mention the documentation seems to have significantly improved. I’ve also been doing a lot of CouchDB work lately so I’ve internalized the “Document Store” concept and once I saw the Expando class provided by AppEngine I felt like I was now in a place where I can really understand Google’s datastore. It’s also not documented very well but Google’s datastore supports some geo data, which has always been a concern of mine putting too many eggs in the CouchDB basket right now. Add the fact that I absolutely hate managing infrastructure and I made a quick decision to invest once again in AppEngine or an upcoming project.

Why I Hate Django

I don’t think anyone will disagree that the highlight of Day One was Cal Henderson talk “Why I Hate Django”, he was absolutely hilarious. The video will be up eventually and I highly suggest everyone watch because it’s just too damn entertaining. I pulled a series of CC pictures from flickr in the meantime that illustrate the humor of the talk.

Cal Hates Django

Cal Hates Django

Cal Hates Django

Cal Hates Django

Cal Hates Django

Cal Hates Django

Cal Hates Django

Live Testing

Something like two years ago I wrote a patch to add live server support to the Django Test Framework (based on unittest). That patch fell out of sync with trunk and on the floor at some point. Eventually an intern at Disqus came along and got it working again and made some really nice improvements.

Although the patch didn’t make it in to Django 1.0 I’m told it should land soon and will be in 3.1, but Disqus has been running with it all summer, using it for some Selenium tests. Well I couldn’t stand idle while Selenium test were running with Django and Windmill tests weren’t so I put my head down for about an hour during one of the talks and committed Django support to Windmill trunk. I ported the current patch for live server support in Django’s Trac so that it dynamically adds what is needed to Django and you can use this with Django 1.0 unmodified, and created a TestCase class that will launch your Windmill tests from within the normal Django python mange.py test runner. I wrote up a bit more about this in a post to the windmill-dev list.

Windmill Reporting

Posted by on September 06, 2008

Adam wrote a great post recently on some code he wrote that outputs his test results in an xml format that Hudson can digest. It serves as an example of a fairly underutilized feature in functest for reporting. It’s incredibly simple and powerful, you add a simple class to the highest level __init__.py with your report code and it will be called when all the tests have finished.

Ideally you want to checkin your reporting mechanism with the source for all your tests but only run the reporter when it runs in continuous integration. Another functest feature is that any unrecognized command line = arguments are stuffed in to dictionary at functest.registry, and there is code in the windmill command line that will do the same.

$ windmill shell report=true                              [14:15]
report is not a windmill argument. Sticking in functest registry.
 
In [1]: import functest
In [2]: functest.registry
Out[2]: {'report': 'true'}

You can use this in your Report class to decide when you should actually report, you can even do different types of reporting based on what you pass. I wrote an example by refactoring Adam’s earlier Hudson example, I’ve also sped up some of the code and use ElementTree to write the xml instead of writing the string output by hand.

import functest
from functest import reports
from xml.etree import ElementTree
 
class JUnitReporter(reports.FunctestReportInterface):
    def summary(self, test_list, totals_dict, stdout_capture):
        if functest.registry.get('report', False):
            total_sec = reduce(lambda x, y: (y.endtime - y.starttime).seconds + x, test_list, 0)
            e = ElementTree.Element('testsuite')
            e.attrib['errors'] = e.attrib['failures'] = str(totals_dict['fail'])
            e.attrib['tests'] = str(len(test_list))
            e.attrib['name'] = 'windmill.functional'
            e.attrib['time'] = str(total_sec)
            for entry in test_list:
                t = entry.endtime - entry.starttime
                test = ElementTree.Element('testcase')
                test.attrib['classname'] = test.attrib['name'] = entry.__name__
                test.attrib['time'] = str(t.seconds)+'.'+str(t.microseconds)
                if entry.result is not True:
                    failure = ElementTree.Element('failure')
                    failure.attrib['type'] = entry.tb[-1].split(':')[0]
                    failure.text = '\n'.join(entry.tb)
                    test.append(failure)
                e.append(test)
 
            if len(stdout_capture):
                # ElementTree doesn't support CDATA so we need to hack it a little
                replace = '#$!#$!replace#@!$'
                sysout = ElementTree.Element('system-out')
                sysout.text = replace
                e.append(sysout)
                outs = ElementTree.tostring(e).replace(replace, '<!--[CDATA['+stdout_capture+']]-->')
            else:
                outs = ElementTree.tostring(e)
 
            f = open('continuous_test.log','w')
            f.write(outs) ; f.close()
 
reports.register_reporter(JUnitReporter())

Windmill has moved!

Posted by on August 29, 2008

We decided a while ago that it would be best to move the windmill project off of OSAF’s infrastructure.

The decision was much easier to come to than the actual execution of the move. I had assumed that the difficult things to migrate would be Trac and that the subversion migration would go by fairly smoothly, I was mistaken. The Trac migration turned out to be much easier than expected, and the subversion migration took hours of fighting with the new server (the culprit ended up being a /usr/local/bin/svnserve hiding out that svn+ssh liked to use instead of /usr/bin/svnserve causing version mismatch problems).

The new hosting is distributed between a personal server of mine ( Trac, subversion, Tutorial) and some hosting that Adam Christian has setup (www.getwindmill.com w/ new Blog) with all the email lists moving to Google Groups.

At the end of the day we have a whole lot of great new infrastructure. The new blog is a great, it’s a Wordpress install with a lot more features than we previously had and new video tutorials. The svn checkin emails are nicer because it’s a newer package. Google Groups is much nicer than MailMan. The subversion server is significantly newer and on the same box as the Trac install which cleaned up the one revision number mismatch we previously had do to using an svk mirror. And we have Google Analytics setup for all the new sites which is going to keep us abreast of articles and events that send new people to the project.

This is getting us all even more excited about the upcoming windmill work and Adam is getting ready to go out promoting windmill more aggressively than it’s ever been pushed before.