Python多线程单元测试
我使用多线程设计(别无选择),但我的大部分代码驻留在单个线程中,其中的所有事件都通过 队列。以这种方式,我的大部分代码的行为就好像它是单线程的,而且我不必担心锁、信号量等等。
唉,我已经到了需要对我的代码进行单元测试的地步(请不要批评我一开始就没有 TDD),而我不知所措 - 如何在另一个线程中测试某些东西?
例如,假设我有以下类:
class MyClass():
def __init__(self):
self.a=0
# register event to self.on_event
def on_some_event(self, b):
self.a += b
def get(self):
return self.a
并且我想测试:
import unittest
from queued_thread import ThreadedQueueHandler
class TestMyClass(unittest.TestCase):
def setUp(self):
# create the queued thread and assign the queue to self.queue
def test_MyClass(self):
mc = MyClass()
self.queue.put({'event_name':'some_event', 'val':1})
self.queue.put({'event_name':'some_event', 'val':2})
self.queue.put({'event_name':'some_event', 'val':3})
self.assertEqual(mc.get(),6)
if __name__ == '__main__':
unittest.main()
MyClass.get()
对于排队线程内的任何内容都可以正常工作,但测试将在主线程中异步调用它,因此结果可能不正确!
I use a multi-threaded design (had no choice), but most of my code resides in a single thread where all events in it are managed via a queue. In this fashion most of my code behaves as if it is single threaded, and I don't have to worry about locks, semaphores and what not.
Alas I've come to the point where I need to unittest my code (please don't lash for not TDDing in the first place), and I'm at a loss - how do you test something in another thread?
For instance, say I have the following class:
class MyClass():
def __init__(self):
self.a=0
# register event to self.on_event
def on_some_event(self, b):
self.a += b
def get(self):
return self.a
and I want to test:
import unittest
from queued_thread import ThreadedQueueHandler
class TestMyClass(unittest.TestCase):
def setUp(self):
# create the queued thread and assign the queue to self.queue
def test_MyClass(self):
mc = MyClass()
self.queue.put({'event_name':'some_event', 'val':1})
self.queue.put({'event_name':'some_event', 'val':2})
self.queue.put({'event_name':'some_event', 'val':3})
self.assertEqual(mc.get(),6)
if __name__ == '__main__':
unittest.main()
MyClass.get()
works fine for anything inside the queued thread, but it will be called asynchronously in the main thread by the test, thus the result may not be correct!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的设计假设所有内容都必须经过队列,那么不要与之对抗 - 让所有内容都经过队列!
将
on_call
事件添加到排队的事件处理程序中,并向其注册以下函数:然后将测试修改为:
If your design assumes everything must go through the queue, then don't fight it - make everything go through it!
Add an
on_call
event to your queued event handler, and register to it the following function:then modify your test to:
您可以查看 test_threading.py stdlib 测试执行与您尝试执行的操作类似的操作。基本思想是使用互斥锁和信号量保护线程执行,以便在断言测试条件之前完成执行。
You can have a look at test_threading.py in the stdlib tests which does something similar to what you are trying to do. The basic idea is to protect a thread execution with mutex and semaphore so that the execution is complete before the test condition is asserted.