Search code examples
pythontwistedtrial

Testing with a twisted deferred


I have been struggling to wrap my head around testing twisted code with deferred's and deferred's in general.

I have a simple test that really should fail, I think.

From my undertstanding in Twisted's test tool Trial, I should be able to return a deferred and when it is finished the test will finish.

Here is my tidbit of code, maybe someone can help.

import unittest, time

from twisted.internet import reactor, defer

class MyTest(unittest.TestCase):

def test_simple_deferred(self):

    print "\nStarting Test"

    my_deferred = defer.Deferred()

    def print_time():
      print time.time()
      self.assertTrue(False)

    my_deferred.addCallback(print_time)

    reactor.callLater(3, my_deferred.callback)

    print time.time()

    return my_deferred

Thanks in advance, I have looked at a lot of examples, but I think I have gotten to the point that I have been looking at this for far too long.


Solution

  • You have two problems.

    Firstly, to get the special deferred handling, your test case needs to inherit from twisted.trial.unittest.TestCase, not the python standard library version.

    Lastly, you are not calling reactor.callLater properly, or rather, you aren't giving it the right arguments for Deferred.callback(); you need to give the deferred a value. If you don't care what it is, give it a None. Likewise, the callback needs to take that argument; you can safely ignore it.

    from twisted.trial import unittest
    #^^^^^^^^^^^^^^^^^
    import time
    
    from twisted.internet import defer
    from twisted.internet import reactor
    
    class MyTest(unittest.TestCase):
    
        def test_simple_deferred(self):
    
            print "\nStarting Test"
    
            my_deferred = defer.Deferred()
    
            def print_time(dont_care):
            #              ^^^^^^^^^
                print time.time()
                self.assertTrue(False)
    
            my_deferred.addCallback(print_time)
    
            reactor.callLater(3, my_deferred.callback, None)
            #                                        ^^^^^^    
            print time.time()
    
            return my_deferred