[Twisted-Python] Running twisted.trial unittests using nose
glyph at divmod.com
glyph at divmod.com
Mon Aug 6 23:15:20 EDT 2007
On 6 Aug, 02:17 pm, andrew-twisted at puzzling.org wrote:
>glyph at divmod.com wrote:
>>Twisted application does, and which is not _really_ supported by the
>>framework: re-start the reactor repeatedly.
>>Eventually, 'trial' itself will not do this, and will behave as a
>>"normal" Twisted application.
Let's start with a point of agreement:
>The reactor can't be comprehensively unittested until multiple
>reactors/restartable reactors are supported anyway, so it should be
>would also make it possible to consider testing multiple different
>implementations in a single test run.
This is absolutely true. The limiting factors on the code being used
this way are simply (A) a lack of reasonable tests, and (B) some
misguided micro-optimizations in the reactor which no longer help
anyway. There is nothing in anyone's preferred design for Trial, mine
included, that would preclude such a thing.
Multiple reactors should, indeed must, eventually be supported. It
would be nice if someone who really wanted it would implement it though,
instead of just talking about it ;).
>I don't think this is the right approach. The right approach is to fix
>to support multiple simultaneous reactors, so that your Twisted test
>wants to do stuff with a reactor is isolated from the tests, and vice
>The tests should then use a fresh reactor for each test. It's simple
Your suggested implementation reinforces the antipattern of "tests are
special and need 'waitFor' or 'blockOn' because they can't be written
otherwise". Then, of course, newbies ask why the tests can have this
but their protocol implementation (which really needs it, seriously,
it's not like *any* other application using Twisted) can't. Aside from
the fact that it might actually work / be tested, it is the same (as far
as I'm concerned) as much of the brokenness that Trial has dealt with
for quite some time.
Much code within and without Twisted uses, and will continue for the
forseeable future to use, "from twisted.internet import reactor" to
access the reactor. One might hope that this usage would eventually be
replaced by something better, but it's not clear if this (or an
equivalent spelling) could ever be *completely* eliminated. I quite
like Jim Fulton's suggestion for adding an ITransport.reactor attribute
and using that in most places where the global import is currently used.
However, even if we had a comprehensive somehow non-global way to get at
a reactor available today, there would still be a *very* lengthy
transition period to a new API. The question will remain what to do
about that code.
My main objection here, though, is that I'd really like to be able to
add nifty Twisted-using features to Trial, and it's basically impossible
right now, due in large part to the fact that the reactor keeps starting
and stopping. Creating a new reactor for each test is going to create
confusing semantics for code written using established idioms, because
either the framework is going to go to a lot of trouble to fool
everything into using trial's idea of the reactor the tests should be
using (which begs the question: how do you test trial itself, if it has
a reference to the "real" reactor?), or it's going to require special
hacks to get at the "real" reactor which still won't behave in an event-
driven way if a test (shock, horror) actually does want to do some real
I/O itself. Although I am *personally* focusing on how to write better
and more isolated unit tests using trial, I know of a small number of
people using it as an integration testing tool that does tons of I/O to
external systems and I think that is an interesting use-case and should
be better supported, not worse.
Perhaps the 'trial' tool itself is a misguided design though, and
'disttrial' will simply replace it in short order. If this is the case,
then the tests are running in a subprocess anyway, and there's no reason
to run any code in-process with the tests, except for things to gather
metrics. In that case, the 'disttrial' tool itself is a real Twisted
program, and the subprocess fakes just enough to get by:
That *particular* hack makes me cringe, but I think the overall
architecture may satisfy us both better in the end.
More information about the Twisted-Python