views:

375

answers:

4

I'm writing unit tests for a portion of an application that runs as an HTTP server. The approach I have been trying to take is to import the module that contains the HTTP server, start it. Then, the unit tests will use urllib2 to connect, send data, and check the response.

Our HTTP server is using Twisted. One problem here is that I'm just not that familiar with Twisted :)

Now, I instantiate our HTTP server and start it in the setUp() method and then I stop it in the tearDown() method.

Problem is, Twisted doesn't appear to like this, and it will only run one unit test. After the first one, the reactor won't start anymore.

I've searched and searched and searched, and I just can't seem to find an answer that makes sense.

Am I taking the wrong approach entirely, or just missing something obvious?

+2  A: 

I believe that for unit testing within Twisted you're supposed to use TwistedTrial (it's a core component, i.e., comes with the Twisted tarball in the twisted/trial directory). However, as the URL I've pointed to says, the doc is mostly by having a look through the source (including sources of various Twisted projects, as they're tested with Trial too).

Alex Martelli
+6  A: 

Here's some info: Writing tests for Twisted code using Trial

You should also look at the -help of the trial command. There'a lot of good stuff in trial! But it's not always easy to do testing in a async application. Good luck!

Etienne
A: 

There is a known bug with Twisted (that probably won't get fixed) where re-starting the reactor causes a crash.

This is why your unit tests don't work.

As well as using Trial you might want to consider seperate testing systems that talk to your HTTP server like a client will.

  • Webdriver - an API to drive a browser session around your site.
  • TestGen4Web - Firefox plugin that records interactions with site and can replay.
Tom Leys
+1  A: 

As others mentioned, you should be using Trial for unit tests in Twisted.

You also should be unit testing from the bottom up - that's what the "unit" in unit testing implies. Test your data and logic before you test your interface. For a HTTP interface, you should be calling processGET, processPOST, etc with a mock request, but you should only be doing this after you've tested what these methods are calling. Each test should assume that the units tested elsewhere are working as designed.

If you're speaking HTTP, or you need a running server or other state, you're probably making higher level tests such as functional or integration tests. This isn't a bad thing, but you might want to rephrase your question.

Karl Anderson
You know I think you're right. Honestly, all I need to do to do lower level unit tests would be to fake the "request" object (some of the functions use that quite a bit).
Dave