[Zope-dev] Re: Test runner: layers, subprocesses, and tear down

Martin Aspeli optilude at gmx.net
Thu Jul 3 19:56:28 EDT 2008


Benji York wrote:
> I'm working on making the zope.testing test runner run tests in
> parallelized subprocesses.

I have some recent experience parallelising (and distributing across 
machines) test runs. This was in Java, with TestNG and Selenium, but we 
learned some interesting things. We basically cut a 45 minute test run 
to 10 minutes by distributing the tests across three machines, each 
running a full stack (Oracle, JBoss, Firefox) and Selenium Grid. I 
realise you're not trying to do anything quite as complex as that, but a 
parallel test runner ought to be extensible to support distribution 
across nodes in a grid. The main challenge there is to distribute 
deployment of the code to run, and to sync test setup so that all 
environments are identical. I suspect you'll find this out of scope to 
begin with, but I'd keep it in the back of your mind.

You will likely need some way of declaring tests that have to run in 
series. Sometimes that's just for sanity's sake, other times it's a 
requirement due to shared resources.

A nice way to do this is to make it possible to annotate tests to group 
them, and then to be able to declaratively configure some groups as 
serial. Any functional test that uses a shared external resource will 
require this. TestNG supports (as far as I recall):

  - Run all tests (methods) randomly and parallelise

  - Run groups of tests (classes or declaratively specified named 
groups) in parallel, but run tests within the groups sequentially

  - Run all tests in series (i.e. single-threaded)

We should probably use test layers as the main grouping mechanism here. 
If you could declare a layer as "can be run in parallel with other 
layers" or "tests in this layer run in series", that'd be pretty 
powerful. I'm not 100% sure how this works with layers that derive from 
one another, and where you'd have two layers with a shared base class, 
though.

Parallisation can offer huge (!) speed increases, but it can also be 
hard to debug tests. I'd be tempted to let single threaded by the 
default, safe choice, and let people opt into parallisation only when 
they know what they are doing. Most test runs are quite quick anyway.

Test result reporting can be difficult. You'll probably need to collect 
all failures with tracebacks and report at the end. For long running 
test suites, this may not be ideal, since it's helpful to get early 
warning, so if you can find a way to get test output to be atomically 
output, then that'd be nice.

Debugging stuff that happens in parallel with pdb is also tricky. It 
must be easy to turn off parallel running and to run individual tests in 
a single process for each debugging.

To make this work with Selenium grid, we ended up building some 
infrastructure to manage environments (i.e. an allocation of database, 
web server and so on), and locks on those environments. We'd spawn one 
thread for each environment and feed tests to those threads as fast as 
they could run them. Each test run then grabbed an environment on setup, 
executed, and then released the lock for another test.

Oh, and please don't get rid of any tear-down. You'll definitely need it 
one day. Letting environments go dirty is generally troublesome, and 
gets only more difficult when you may have multiple threads trying to 
use those environments at once. I don't know how you've structured this, 
but I'd consider whether one layer could be shared across multiple 
threads/subprocesses, or if it's always a one-to-one thing.

I realise this is somewhat rambling, but I hope it's useful in any case. :)

Cheers,
Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book



More information about the Zope-Dev mailing list