[Twisted-Python] Testing Twisted code without trial
Adi Roiban
adi at roiban.ro
Mon Mar 18 13:32:00 MDT 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