[Twisted-Python] Testing Twisted code without trial

Adi Roiban adi at roiban.ro
Mon Mar 18 15:32:00 EDT 2013


On 22 January 2013 22:03,  <exarkun at twistedmatrix.com> wrote:
> On 09:29 am, adi at roiban.ro wrote:
>>On 22 January 2013 02:21,  <exarkun at twistedmatrix.com> wrote:
>>>On 20 Jan, 02:35 pm, adi at roiban.ro wrote:

I agree that this is a ugly hack and I removed the project.

>
> Hi Adi,
>
> trial does what it does by touching a lot of internal stuff as well.
> This is still bad, but at least it's our fault if it ever breaks instead
> of yours.  There's also a long term plan (or "plan" may be putting it
> too strongly, perhaps I should say "hope") that this part of trial will
> change to only use public interfaces.  This will probably require
> reactors actually implementing restartability, or it will require
> changing the trial feature slightly (eg, so it starts a reactor, runs
> all tests, then stops the reactor - if it did this, I'm sure you can
> imagine how "waiting" for a Deferred would just be adding a callback to
> the right place, as in any other Twisted-based application).
>
> Are you interested in helping out with making reactors restartable? :)

Sorry for the late reply.

I am still clumsy when working with Twisted so I don't know if I can
help to much here.

I don't know what is expected from a restartable reactor.

The way I am testing deferreds is by starting the reactor, allow for
the deferred to execute and then stop the reactor.

I don't want to pause it and then continue the execution from where it
was stopped.

To help with debugging I am also printing a snapshot of reactor state
at a certain time.

----

I prefer the Arrange/Act/Assert way of writing test:


checker = mk.credentialsChecker()
credentials = mk.credentials()

deferred = checker.requestAvatarId(credentials)
failure = self.getDeferredFailure(deferred)

self.assertFailureType(AuthentiationError, failure)
self.assertEqual(credentials.username, failure.value.username)


I found it easier to read than this version:


checker = mk.credentialsChecker()
credentials = mk.credentials()

    def check_result(result_or_failure):
        self.assertFailureType(AuthentiationError, failure)
        self.assertEqual(credentials.username, failure.value.username)

deferred = checker.requestAvatarId(credentials)
deferred.addBoth(check_result)

return deferred

--------

I have updated the code to use as many public reactor members as possible.

The following private member are still use:
reactor._startedBefore, reactor._started

It uses the following public methods:
startRunning(), doIteration(), stop(), iterate()

Here is the main part that blocks the execution until the deferred got a result.
It executes the deferred in the reactor loop.

https://github.com/chevah/empirical/blob/master/chevah/empirical/testcase.py#L240

------

Maybe this is has only limited usage, but I just wanted to share this work.
For me, this makes writing test a much nicer experience.

Cheers,
-- 
Adi Roiban



More information about the Twisted-Python mailing list