views:

83

answers:

1

Hello,

some small application I'm developing uses a module I have written to check certain web services via a REST API. I've been trying to add unit tests to it so I don't break stuff, and I stumbled upon a problem.

I use a lot of signal-slot connections to perform operations asynchronously. For example a typical test would be (pseudo-Python), with postDataDownloaded as a signal:

def testConnection(self):

    "Test connection and posts retrieved"

    def length_test():
        self.assertEqual(len(self.client.post_data), 5)

    self.client.postDataReady.connect(length_test)
    self.client.get_post_list(limit=5)

Now, unittest will report this test to be "ok" when running, regardless of the result (as another slot is being called), even if asserts fail (I will get an unhandled AssertionError). Example when deliberatiely making the test fail:

Test connection and posts retrieved ... ok
[... more tests...]

OK

Traceback (most recent call last):
[...]
AssertionError: 4 != 5

The slot inside the test is merely an experiment: I get the same results if it's outside (instance method).

I also have to add that the various methods I'm calling all make HTTP requests, which means they take a bit of time (I need to mock the request - in the mean time I'm using SimpleHTTPServer to fake the connections and give them proper data).

Is there a way around this problem?

+1  A: 

You need to avoid exiting the test method until the callback has been called. I believe the call is going to happen in a separate thread, so a threading.Event seems appropriate:

import threading

...

def testConnection(self):
    "Test connection and posts retrieved"

    self.evt = threading.Event()

    def length_test():
        self.evt.set()

    self.client.postDataReady.connect(length_test)
    self.client.get_post_list(limit=5)
    self.evt.wait()
    self.assertEqual(len(self.client.post_data), 5)
Alex Martelli
Thanks for the suggestion, I'll give it a shot later tonight.
Einar