On July 25, 2014 at 9:08:46 AM, Tobias Oberstein (tobias.oberst...@gmail.com) 
wrote:

>> In Twisted, there is Trial, which provides an extended version of 
>> unittest.TestCase with this feature: 
>> 
>> """ 
>> The main unique feature of this testing class is the ability to return a 
>> ​Deferred from a test-case method. A test method which returns a 

snip 

> I strongly recommend you reconsider doing this. 
> 
> The Twisted core developers have, for several years now, mostly eschewed 
> the usage of returning Deferreds from test cases. Instead, tests are 

Are you referring to Twisted code or to _user_ code (on top of Twisted)? 


Yes, both.





I am asking since 

http://twistedmatrix.com/documents/current/core/howto/trial.html#testing-a-protocol
 

seems to encourage writing unit tests for user code with test methods 
returning deferreds. In fact, this document is what I used for guidance. 
Is it outdated? 


Sadly, yes. 


> written by explicitly controlling all events explicitly, with careful 
> use of test doubles to replace certain features of the event loop. 
> There’s also a class in Trial, “SynchronousTestCase”, which offers 
> utilities such as synchronousResultOf(Deferred) -> result and 
> synchronousFailureOf(Deferred) -> result, which both assume the Deferred 
> has fired synchronously (which your test case can ensure). The testing 
> philosophy in Twisted is: if you need the global event loop to really 
> truly run, it’s not a unit test. 
> 
> Trial’s return-a-Deferred feature is still useful in certain integration 
> test situations, where you really want to talk to the Internet or 
> interact with the user in your set of test suites, but for unit tests, 
> it’s possible to exercise all code paths before the test method returns. 

Is there any document on this best practice - applied to testing user 
code, including protocols? 


Well, what you found is it, but it needs updating. Sorry :(




And: I'm sure Twisted developer's will have reasons for frowning upon 
tests returning deferreds, but could you recap shortly why? 


It has the classic problem with bad tests: reliance on global state which is 
not controlled by the test. Unit tests should be isolated, they should not 
affect or rely on external state. When they do, you’re much more likely to run 
into Spooky Action At A Distance[1]. It’s also hard to debug when things go 
wrong — often you’re left with a frozen test suite and no useful diagnostic 
output when there’s a bug.

As my friends David Reid and Alex Gaynor like to say: “Call a function, pass it 
some arguments, look at the return value”.


1: https://en.wikipedia.org/wiki/Action_at_a_distance_%28computer_programming%29

Thanks for your hints, 
/Tobias 


Sure thing! :)

-- 
Christopher Armstrong
http://twitter.com/radix
http://wordeology.com/

Reply via email to