在线程中测试Python代码而不进行修改?
假设我有一个长时间运行的执行线程,用来轮询事件并触发其他事件(在我的例子中,使用XMLRPC调用)。它需要被重构成干净的对象,这样才能进行单元测试,但与此同时,我想在一些集成测试中捕获它当前的一些行为,将其视为一个黑匣子。例如:在线程中测试Python代码而不进行修改?,python,testing,Python,Testing,假设我有一个长时间运行的执行线程,用来轮询事件并触发其他事件(在我的例子中,使用XMLRPC调用)。它需要被重构成干净的对象,这样才能进行单元测试,但与此同时,我想在一些集成测试中捕获它当前的一些行为,将其视为一个黑匣子。例如: # long-lived code import xmlrpclib s = xmlrpclib.ServerProxy('http://XXX:yyyy') def do_stuff(): while True: ... if
# long-lived code
import xmlrpclib
s = xmlrpclib.ServerProxy('http://XXX:yyyy')
def do_stuff():
while True:
...
if s.xyz():
s.do_thing(...)
_
最后一个大问题是,被测试的代码被设计为永远运行,直到出现Ctrl-C,我看不到任何方法来强制它引发异常或以其他方式终止线程,这样我就可以从头开始,而无需更改正在测试的代码。一旦调用被测函数,我就无法轮询线程中的任何标志
我知道这并不是设计测试的目的,集成测试的价值有限,等等,但我希望通过温和地进行测试,而不是一次性地完全重新设计他的软件,向朋友展示测试和良好设计的价值
最后一个大问题是,被测试的代码被设计为永远运行,直到出现Ctrl-C,我看不到任何方法来强制它引发异常或以其他方式终止线程
测试驱动开发的要点是重新思考您的设计,使其可测试
“永远循环”(Loop forever)虽然看起来适合生产使用,但不稳定
因此,使循环终止。这不会影响生产。它将提高可测试性
“设计为永远运行”并不是为可测试性而设计的。因此,请将设计修改为可测试的。我想我找到了一个解决方案,可以满足我的要求:使用单独的进程,而不是使用线程
我可以编写一个小型python存根来进行模拟,并以可控的方式运行代码。然后,我可以编写实际的测试,在子流程中为每个测试运行存根,并在每个测试完成时终止它。测试过程可以通过stdio或socket与存根交互。所有有效点,但如果我在寻找关于良好开发实践的一般建议,我就不会问这个关于后勤的问题。@Mu Mind:如果有明显的,简单的解决方案。
# 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