2011-01-26 59 views
2

比方说,我有这样一组代码,它是一个长时间运行的执行线程,用于轮询事件并引发其他事件(在我的情况下,使用XMLRPC调用)。它需要被重构为干净的对象,所以它可以进行单元测试,但同时我想在某些集成测试中捕获它的一些当前行为,将它当作黑盒子对待。例如:在没有修改的线程中测试Python代码?

# long-lived code 
import xmlrpclib 
s = xmlrpclib.ServerProxy('http://XXX:yyyy') 
def do_stuff(): 
    while True: 
     ... 
     if s.xyz(): 
      s.do_thing(...) 

_

# test code 
import threading, time 
# stub out xmlrpclib 
def run_do_stuff(): 
    other_code.do_stuff() 

def setUp(): 
    t = threading.Thread(target=run_do_stuff) 
    t.setDaemon(True) 

def tearDown(): 
    # somehow kill t 
    t.join() 

def test1(): 
    t.start() 
    time.sleep(5) 
    assert some_XMLRPC_side_effects 

最后一个大的问题是,在测试的代码被设计为永远运行,直到按Ctrl-C,我看不出有什么办法强迫它会引发异常或以其他方式杀死线程,因此我可以在不改变正在测试的代码的情况下从头启动它。一旦我调用被测函数,我就失去了从线程轮询任何标志的能力。

我知道这是真的没有如何设计测试工作,集成测试是有限的价值等,等等,但我希望通过轻柔工作向朋友展示测试和良好设计的价值而不是完全重新设计他的软件。

回答

0

我想我找到了一个解决方案,可以完成我一直在寻找的任务:不使用线程,而是使用单独的进程。

我可以编写一个小型的python stub来模拟并以受控的方式运行代码。然后,我可以编写实际的测试,在每个测试的子进程中运行我的存根,并在每次测试完成后将其杀死。测试过程可以通过stdio或套接字与存根交互。

4

最后一个大的问题是,在测试的代码被设计为永远运行,直到按Ctrl-C,我看不出有什么办法,迫使它抛出一个异常或以其他方式杀死线程

测试驱动开发的重点在于重新考虑您的设计,使其可测试。

循环永远 - 虽然看起来很好的生产使用 - 是不可测的。

所以让循环终止。它不会伤害生产。它会提高可测性。

“设计永远运行”不是为可测试性设计的。所以修复设计是可测试的。

+0

所有有效的点,但如果我正在寻找关于良好开发实践的一般建议,我不会问这个关于物流的问题。 – 2011-04-01 18:28:39

相关问题