Допустим, у меня есть этот блок кода, который создан для того, чтобы быть одним продолжительным потоком выполнения, чтобы опрашивать события и запускать другие события (в моем случае, с использованием вызовов XMLRPC). Он должен быть преобразован в чистые объекты, чтобы его можно было тестировать модульно, но пока что я хочу зафиксировать некоторые из его текущих действий в некоторых интеграционных тестах, рассматривая его как черный ящик. Например:
# 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, и я не вижу способа заставить его вызвать исключение или иным образом уничтожить поток, чтобы я мог его запустить с нуля без изменения кода, который я тестирую. Я теряю возможность опрашивать любые флаги из моего потока, как только я вызываю тестируемую функцию.
Я знаю, что это на самом деле не то, как тесты предназначены для работы, интеграционные тесты имеют ограниченную ценность и т. Д., И т. Д., Но я надеялся показать ценность тестирования и хороший дизайн другу мягко работая над этим, а не полностью переделывая его программное обеспечение за один раз.